面试题答案
一键面试1. 传入NSString对象时内存变化
- 赋值过程:当把一个
NSString
对象赋值给用copy
修饰的属性时,实际发生的是浅拷贝。因为NSString
本身是不可变的,系统为了优化性能,不会重新开辟内存创建一个新的字符串对象。而是让属性直接指向传入的NSString
对象,引用计数加1。 - 内存变化:没有新的内存分配用于存储字符串内容,只是属性的指针指向了已有的
NSString
对象,对象的引用计数增加。
2. 传入NSMutableString对象时内存变化
- 赋值过程:当把一个
NSMutableString
对象赋值给用copy
修饰的属性时,发生的是深拷贝。系统会创建一个新的NSString
对象(因为用copy
修饰后属性的类型是不可变的NSString
),并将NSMutableString
的内容复制到新创建的对象中。 - 内存变化:会开辟新的内存空间来存储新创建的
NSString
对象及其内容,新对象的引用计数为1,而原NSMutableString
对象不受影响,引用计数不变。
3. 这样设计的意义
- 数据保护:使用
copy
修饰属性可以防止外部对对象内部数据的意外修改。比如如果属性是一个字符串,当传入一个可变的NSMutableString
时,若没有copy
操作,外部仍然可以修改这个字符串,可能导致对象内部状态的不一致。而通过copy
操作,属性持有一个不可变的副本,保证了数据的安全性。 - 遵循不可变原则:在很多情况下,对象的某些属性应该是不可变的,以确保对象状态的稳定性和可预测性。使用
copy
可以确保属性值一旦确定就不会被意外改变。
4. 深拷贝和浅拷贝概念
- 浅拷贝: 只复制指向对象的指针,而不复制对象本身,新旧对象共享同一块内存。就像传入
NSString
对象时,属性只是指针指向原对象,并没有复制对象内容。 - 深拷贝:会创建一个全新的对象,并将原对象的内容复制到新对象中,新旧对象位于不同的内存位置。如传入
NSMutableString
对象时,会创建新的NSString
对象并复制内容。