相信大家都使用过strong修饰过string属性,然后对于一般有点经验的人都会是用copy,这是为什么呢?然而自己使用strong修饰好像也没出现啥问题呀,疑惑了?。
那么到底在修饰string属性的时候使用copy和string有啥区别呢?接下来我就一一唠叨唠叨。
1、原字符串为不可变的情况
首先我先看一个例子
可以看到strong和copy的地址都和normal一样,所以值也是一样的。
解结下来我们改变normal的值
可以看到normal重新赋值后,地址发生了变化,指针指向了一块新的地址。然而并没有影响到strong和copy的值和地址。即strong的值和copy的地址没有任何变化。
总结:如果原字符串为不可变类型字符串,使用copy或strong修饰NSString效果是一样的。并且字符串修改值后并不会影响其他属性的值。
2、原字符串为可变的情况
看例子:
可以看到strong和copy的值虽然一样,但是地址不同,至于为啥不同,后面解释。先来修改mutableStr的值
可以看到修改了mutableStr的值,strong会跟着改变了,而copy却不会不会改变。这也就是他们为啥喜欢用copy不使用strong的原因了。因为修改当前属性的值会引起其他值的改变,如果由于这个引起bug,在项目里很难找出来,何不都用copy呢,所以就只要是声明string都选择使用copy了。
3、然而改值是以copy的形式实现的就另当别论了。
看控制台打印的结果,mutableStr重新以copy的形式负值,并不会印象到其他的值。
4、为啥可变字符串更值的时候不会影响到copy的属性值的?
其实道理很简单,因为copy属性重新负值的时候就相当于在set方法里进行了一个copy操作。
- (void)setStrCopy:(NSString *)strCopy{
_strCopy = [strCopy copy];
}
所以strCopy属性会重新分配内存地址。当改变mutableStr的值的时候,只会更改strStrong属性,而不会更改copy的值。
而对mutaleStr进行mutableCopy修改时就不会影响strong值了,因为这是深拷贝,使得mutaleStr成为了一个全新的独立的对象了,自然就不是再影响到其他值了。
所以一些人说:
使用copy修饰字符串是为了防止修改这个属性时,会同时修改了原对象的值。
这个说法是不完全对的,为了防止在把一个可变字符串在未使用copy方法时赋值给这个字符串对象时,修改原字符串时,本字符串也会被动进行修改的情况发生,才使用copy的。