相信大家都使用过strong修饰过string属性,然后对于一般有点经验的人都会是用copy,这是为什么呢?然而自己使用strong修饰好像也没出现啥问题呀,疑惑了?。

那么到底在修饰string属性的时候使用copy和string有啥区别呢?接下来我就一一唠叨唠叨。

1、原字符串为不可变的情况

首先我先看一个例子

ios开发复制某个字符串 ios字符串为什么用copy_可变字符串

可以看到strong和copy的地址都和normal一样,所以值也是一样的。

解结下来我们改变normal的值

ios开发复制某个字符串 ios字符串为什么用copy_赋值_02

可以看到normal重新赋值后,地址发生了变化,指针指向了一块新的地址。然而并没有影响到strong和copy的值和地址。即strong的值和copy的地址没有任何变化。

总结:如果原字符串为不可变类型字符串,使用copy或strong修饰NSString效果是一样的。并且字符串修改值后并不会影响其他属性的值。

2、原字符串为可变的情况

看例子:

ios开发复制某个字符串 ios字符串为什么用copy_可变字符串_03

可以看到strong和copy的值虽然一样,但是地址不同,至于为啥不同,后面解释。先来修改mutableStr的值

ios开发复制某个字符串 ios字符串为什么用copy_可变字符串_04

可以看到修改了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的。