



















不管是用什么语言开发,字符串应该算是用的最多的了。在Objective-C中,字符串类是NSString,以及其子类NSMutableString等。所以,对于字符串类,编程语言、编译器等往往会做特殊处理。下面我就说说我自己在项目中发现的NSString的“奇怪”的地方。
先看看如下面的代码,猜猜会输出什么:
1 | NSString *str1 = @"abc"; |
直接给出结果:
1 |
|
看,是不是很“神奇”。
NSString是“不可变(immutable)”的类型,这个是关键。
代码中的“@”开头的字符串,其实就是一个字符串常量,运行时会检测这个字符串是否已经存在,存在的话,就直接将这个字符串的地址赋给变量;不存在的话,则创建,再赋值。
第一行: “abc”字符串不存在,创建,取得字符串地址“0x10cd12040”,赋给str1.
第二行: “abc”字符串已经存在,直接将地址“0x10cd12040”赋给str2.
第三行: (记住,NSString是不可变的)alloc并不会分配新的内存,直接将字符串地址“0x10cd12040”赋给str3.
第四行: copy,既然是不可变的,也就没有必要分配新内存,直接将地址“0x10cd12040”赋给str4.
第五行: mutableCopy其实就是创建一个NSMutableString的实例,既然是“可变(mutable)”的类型了,当然要分配新的内存,所以,字符串的地址也变成新的“0x7f874b508350”。
可以这么说,编译器、runtime充分利用了NSString是“不可变(immutable)”类型这个特点,只要字符串内容一致,就不会分配新的内存储存,字符串在程序中使用量非常大,这么做无疑可以大大节省内存,提升性能。
先来看看一个UserEntity类:
1 |
|
只有一个名为name的NSString类型Property。
相信大家对这个不陌生吧。一般我们的应用中会有很多Entity类型,每个Entity类里面肯定避免不了有许多NSString的字符串类型。这里的name的属性是:strong和nonatomic,strong表明name要“持有”一份name所指的字符串的引用,nonatomic表示property类型不用加锁。
接着咱们看看下面的代码:
1 | UserEntity *userEntity = [UserEntity new]; |
猜猜会输出什么?
1 | Name: tutuge blog |
看,我们明明是保存的“tutuge”,怎么到后面输出的是“tutuge blog”?
因为name的Property属性是strong的,所以赋值后,它跟showName均指向同一个NSMutableString实例,如下:

所以改变了showName,当然name输出的值也就变了。
这个时候,name的property属性就不能是strong了,应该是copy,如下:
1 |
|
这样的话,当“userEntity.name = showName;”这句运行后,内存布局如下:

这样,就避免了这个问题。
很所时候,代码并不是看上去那样“运行”的,多试试,多查阅资料,就能了解其中的奥秘了~
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。