Constant pointers 常量指针

区别于 Swift 开发者习惯创建常量,Objective-C 开发者习惯性创建变量。如果你随机抓一个 Objective-C 开发者,问他「怎么样能创建一个常量字符串呢?」有一半的概率是,他会答错这一题。

下面的这段代码是不会被编译的:

const i = 10;
i = 20;

因为你不能在创建了一个常量之后,再去改变它,但是下面这段代码就可以:

const NSString *first = @"Hello";
first = @"World";

你也可以这么写:

NSString const *first = @"Hello";
first = @"World";

搞清楚其中的原因非常重要。这两种写法都表示了「这些字符串不能改,但是指针随意」,记住,在 Objective-C 里,所有的对象都是指针。所以这两句话的意思就相当于「只要你不要改变我的房子,这些路标随便指」。

NSString 是一个不能改变的类,这个意思是,当它设定好初始值之后,值就不能再改了。当你觉得你在改值的时候,其实所做的是把原来的字符串销毁,再创建一个新的字符串,同时更新指针。

我们可以用 NSLog() 的 %p 格式来验证这一点。 "%p" 的意思是「打印该对象的指针」。它在 debug 的时候非常好用,因为它可以帮你追踪内存里具体某个对象的值。在我们的这个例子里面,我们就能够看到,指针在创建新对象的时候改变了。来运行一下下面的代码:

NSString *first = @"Hello";
NSLog(@"%p", first);
first = @"World";
NSLog(@"%p", first);

我在运行的时候,控制台显示是这样的:

2016-05-06 11:56:55.204 OCTest[57100:15178322] 0x100001038
2016-05-06 11:56:55.205 OCTest[57100:15178322] 0x100001078

我们可以看到,在一开始的时候,这个字符串的内存地址是 0x100001038,但是之后它就变成了 0x100001078,这就说明了指针发生了改变。

如果我们想要创建一个绝对不会被改变的字符串,我们要用的是使用「常量指针」。因为 NSString 这个类本身就是一个常量类,它是不能被改变的。那我们只要确保的是没有人动了我们的路标就可以了。具体怎么做呢?我们需要把 const 移到指针的星号后面,就像这样:

NSString * const first = @"Hello";

results matching ""

    No results matching ""