2

If I have a C-string like this:

const char* str= "hello";

I know well that I can't change any character of the string because the pointer is const.
But if I have this:

- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location

I can still mutate the object state using it's methods.
If the pointer is to a NSMutableString, I'm still able to mutate it.
Then what does the const stand for?

4

3 回答 3

1

注意区别:

// constant pointer
char * const str = "";

// pointer to constant (two equivalent ways)
const char * str = "";
char const * str = "";

关键字 const 适用于紧靠其左侧的任何内容。如果它的左边没有任何东西,它适用于它右边的任何东西。

在 Objective-C 中,所有方法参数总是按值传递。这包括原语、结构、联合和指针,以及任何其他组成的类型。

请注意,您不能拥有 object 类型的变量。像这样的表达式NSObject o;会产生编译器错误,并显示消息“无法静态分配接口类型”。

传递对象的唯一方法是传递指针。指针作为值传递,但让方法内的代码引用对象并更改它。所以在某种程度上,就好像你通过引用传递对象(实际上你是通过值传递指针)。

在编译 Objective-C 程序时,方法被转换为 C 函数,并且每个“消息发送”(也称为“方法调用”,虽然并不完全相同)都使用运行时函数运行objc_sendMsg。这个函数不知道也不关心你是否对对象进行了限定const。如果您想要一个不可变对象,则必须在对象内部编写该不可变性代码。例子:

// const qualifying an object is ignored whether in variables or method arguments:
const NSMutableArray *array = [NSMutableArray new];   // const is ignored
-(void)someMethod:(const NSMutableArray *)array { ... // const is ignored

// calling the methods that mutate the object works fine
[array removeAllObjects];
于 2012-11-30T20:23:31.713 回答
1

在该方法声明中,location是一个指向常量的指针CLLocationlocation但是当您向对象发送消息时,const不会保留 -ness;处理消息的方法被self视为非const对象。(请注意,这与 C++ 不同,后者支持const成员函数,其中this是指向常量对象的指针。)

所以const那个声明中的 并不是特别有用。也许它是由习惯于 C++ 做事方式的人编写的。

当您const在 Objective-C 中看到附加到对象指针时,通常是这样的:

extern NSString * const SomeConstantString;

这声明SomeConstantString为指向某个非常量对象(在本例中为 an NSString)的常量指针。指针本身是常量,因此您的程序不能更改SomeConstantString为指向其他NSString对象。

于 2012-11-30T20:30:52.753 回答
1

我很清楚我不能更改字符串的任何字符,因为指针是 const。

不,指针是可变的。它指向的字符是 const。

我仍然可以使用它的方法改变对象状态。

Objective-C 对象没有像 C++ 中那样的 const 正确性。编译器不关心您发送到 const 对象的消息(变异与否)。所以声明一个指向 const 对象的指针是没有意义的。引用的框架方法是异常的,可能是疏忽。

于 2012-11-30T20:31:18.190 回答