NSString什么时候用copy,什么时候用strong
结论:一般情况下,我们都不希望字串的值跟着mutableStr变化,所以我们一般用copy来设置string的属性。
如果希望字串的值跟着赋值的字串的值变化,可以使用strong,retain。
注意:上面的情况是针对于当把NSMutableString赋值给NSString的时候,才会有不同,如果是赋值是NSString对象,那么使用copy还是strong,结果都是一样的,因为NSString对象根本就不能改变自身的值,他是不可变的。
把一个对象赋值给一个属性变量,当这个对象变化了,如果希望属性变量变化就使用strong属性,如果希望属性变量不跟着变化,就是用copy属性。
重点由此可以看出:
对源头是NSMutableString的字符串,strong仅仅是指针引用,增加了引用计数器,这样源头改变的时候,用这种strong方式声明的变量(无论被赋值的变量是可变的还是不可变的),它也会跟着改变;而copy声明的变量,它不会跟着源头改变,它实际上是深拷贝。
对源头是NSString的字符串,无论是retain声明的变量还是copy声明的变量,当第二次源头的字符串重新指向其它的地方的时候,它还是指向原来的最初的那个位置,也就是说其实二者都是指针引用,也就是浅拷贝。
NSArray什么时候用copy,什么时候用strong
同样的道理
由打印结果可知,被strong修饰的array 随着mutableArray的变化而变化,而被copy修饰的array并没有变化。
使用strong,则strongArray与可变数组mutableArray指向同一块内存区域,mutableArray内容改变,导致strongArray的内容改变,因为两者是同一个东西;而使用copy,copyArray在赋值之前,将mutableArray内容复制,创建一个新的内存区域,所以两者不是一回事,mutableArray的改变不会导致copyArray的改变。
综上所述:
当修饰可变类型的属性时,如NSMutableArray、NSMutableDictionary、NSMutableString,用strong。
当修饰不可变类型的属性时,如NSArray、NSDictionary、NSString,用copy。
把NSMutableArray用copy修饰有时候就会crash,因为对这个数组进行了增删改操作,而copy后的数组变成了不可变数组NSArray,没有响应的增删改方法,所以对其进行增删改操作就会报错。
如果是strong,直接是赋值;右边是什么,左边就是什么,并且是强引用新值,左边的类型会与右边的相同,不会改变。
NSMutableArray区分两种情况,第一种:copy属性与setter赋值
第二种,不会出现crash的
self.testCopyMutableArray设为copy属性之后,利用setter赋值拷贝的是不变的数据即NSArray,所以方法2会崩溃,而方法1是直接给变量赋值,应该是默认的__strong 属性,
说明是强引用关系
另外函数内开辟的空间,如果通过返回值返回回来之后是会一直存在的,直到autorelease}结束。
说明内部定义的变量是属于强引用,也就是说变量的默认属性是强引用,除非定义了weak
上述例子也说明retain/copy/assign是在setter内实现的,如果跳过setter上述属性将会失效
weak属性用不用setter是一样的
unsafe_unretain与weak的区别在于,当被引用的对象置为nil后,weak变量也会置为nil, 而unsafe_unretain的则变成野指针,访问可能会崩溃。
NSString *a = @”test”;
__weak NSString *b = a;
b = nil;
//此时对b的修改并不影响a; 但是如果是a修改的话,b的值也会一起变化
上述引用地址:https://blog.youkuaiyun.com/kongdechao/article/details/49455491