做iOS开发的需要学习内存管理,有一些概念在工作和面试中常常遇到:什么是深拷贝,什么是浅拷贝?
mutableCopy
和copy
有什么区别? 为啥NSString
通常是copy
?感觉网上一些资料讲的不是很清楚,这里说明几点:
1. 什么是浅拷贝、深拷贝?
A: 简单理解就是,浅拷贝是拷贝了指向对象的指针, 深拷贝不但拷贝了对象的指针,还在系统中再分配一块内存,存放拷贝对象的内容。
2. 如何判断浅拷贝、深拷贝?
A: 深浅拷贝取决于拷贝后的对象的是不是和被拷贝对象的地址相同,如果不同,则产生了新的对象,则执行的是深拷贝,如果相同,则只是指针拷贝,相当于retain一次原对象, 执行的是浅拷贝.
举个栗子🌰
深切拷贝取决于是否为对象分配了新的内存地址,否则就是指针Copy.
此处上码:
1 | NSString *str1 = [NSString string]; |
运行结果:
其实常用的Foundation
框架类型,比如NSString
,浅拷贝,也就是木有产生新对象的情况,只有一种,就是不可变对象使用copy操作,借用网上的一张图:
其他的比如NSArray
、NSDictionary
类似,可以参考 汉斯哈哈哈的文章
3. 为啥NSString
通常用copy
?什么时候用strong
?
A: 因为在使用NSString
的时候,一般如果初始化后不想改变这个NSString
的值,应该将其类型设为copy
,如果用strong
类型,比如NSString
用NSMutableString
赋值,指向其地址,当NSMutableString
的值被改变时,这个NSString
值也发生了变化,如果是copy修饰的NSString对象,在用NSMutableString
给他赋值时,会进行深拷贝,即把其内容也给拷贝了一份,两者指向不同的位置,即使改变了NSMutableString
的值,NSString
的值也不会改变.
参考stackoverflow的问题 NSString property: copy or retain?
Youtube上一个很不错的视频说明了这个问题:Why you might use copy instead of strong in an Objective-c @property
上码:
1 | @property (nonatomic, strong) NSString *aStrongStr; |
4. 还需要注意一点,mutableCopy
返回的是可变对象,copy
返回的是不可变对象。
1 | NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithObjects:@1, @2, nil]; |
虽然array
定义的是NSMutableArray
, 其实是copy方法返回的一个不可变的数组,所以在执行addObject的方法会报错。
问题:NSString什么时候用copy,什么时候用strong
引用一篇文章: NSString什么时候用copy,什么时候用strong
把一个对象赋值给一个属性变量,当这个对象变化了,如果希望属性变量变化就使用strong属性,如果希望属性变量不跟着变化,就是用copy属性。
所以,如果一般情况下,我们都不希望字串的值跟着NSMutableString
变化,所以我们一般用copy
来设置string的属性。
如果希望字串的值跟着赋值的字串的值变化,可以使用strong
注意:上面的情况是针对于当把 NSMutableString
赋值给NSString
的时候,才会有不同,如果是赋值是NSString
对象,那么使用copy
还是strong
,结果都是一样的,因为NSString
对象根本就不能改变自身的值,他是不可变的。
1 | [immutableObject copy] // 浅复制 |
参考:
- NSString什么时候用copy,什么时候用strong
- NSString属性什么时候用copy,什么时候用strong?
- NSString特性分析学习
- iOSInterviewQuestions/《招聘一个靠谱的iOS》面试题参考答案(上).md at master · ChenYilong/iOSInterviewQuestions
如果有误,欢迎拍砖~