1. iOS中的拷贝与retain
retain 属性表示两个对象地址相同,内容也相同,这个对象的引用计数器+1。
2. 什么时候是深拷贝,什么时候是浅拷贝
系统的非容器类对象指的是 NSString,NSNumber 这些不能包含其他对象的对象。在非容器类对象中,对不可变对象进行copy操作,是浅拷贝,mutableCopy操作是深拷贝。对可变对象进行copy和mutableCopy都是深拷贝,但是 copy 返回的对象是不可变的。
copy | mutableCopy | |
---|---|---|
NSString | NSString 浅拷贝 | NSMutableString 深拷贝 |
NSMutableString | NSString 深拷贝 | NSMutableString 深拷贝 |
NSArray | NSArray 浅拷贝 | NSMutableArray 深拷贝 |
NSMutableArray | NSArray 深拷贝 | NSMutableArray 深拷贝 |
NSDictionary | NSDictionary 浅拷贝 | NSMutableDictionary 深拷贝 |
NSMutableDictionary | NSDictionary 深拷贝 | NSMutableDictionary 深拷贝 |
对集合类对象的深拷贝, 通常也只是单层深拷贝。如下图所示,NSMutableArray 即使设置copyItems参数为YES, 也只是单层的深拷贝。
copyItems参数为YES,作用是集合里的每个对象都会收到 copyWithZone: 消息。如果集合里的对象遵循 NSCopying 协议,那么对象就会被深复制到新的集合。如果对象没有遵循 NSCopying 协议,而尝试用这种方法进行深复制,会在运行时出错。copyWithZone: 这种拷贝方式只能够提供一层内存拷贝(one-level-deep copy),而非真正的深复制。
想要通过拷贝得到一个全新的对象,一种可行的方案是通过NSKeyedArchiver类对对象进行归档及解归档:
3. 为什么NSString类型的成员变量的修饰属性用copy而不是strong
这是因为有时候赋给该成员变量的值是NSMutableString类型的,这时候如果修饰符是strong,那成员变量的值就会随着被赋值对象的值的变化而变化。若是用copy修饰,则对NSMutableString类型的值进行了一次深拷贝,成员变量的值就不会随着被赋值对象的值的改变而改变。
4. 对NSMutableString用copy修饰会有什么问题?
对NSMutableString用copy修饰得到的是不可变类型NSString对象,如果再对这个对象进行改变会crash。
NSString与NSMutableString的区别主要是:NSMutableString对象所指向内存地址中的内容可以被修改,而NSString对象所指向内存地址中内容不能被修改,但NSString对象不是常量,可以通过为NSString对象重新分配一块内存来改变其指向的内容。