NSCopy-NSMutablecopy
- 浅拷贝:不产生新的对象,直接指向原有对象 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间。
- 深拷贝:产生新的对象(新地址),其内容是原有对象的内容
NSCopy拷贝出的结果是不可变对象,跟其接受类型没有关系,跟其传入类型也没有关系,NSMutablecopy拷贝的结果是可变对象,跟其传入的类型没有关系,但是会受其接收类型的影响,
当使用NSCopy复制一个不可变对象时,其行为是浅复制,其余情况都是深拷贝
当使用NSMutablecopy时,是深拷贝
如下:
拷贝行为属于 | 拷贝出的结果 | ||
NSCopy | 复制一个不可变对象 | 浅复制 | 不可变对象 |
复制一个可变对象 | 深拷贝 | ||
NSMutablecopy | 深拷贝 | 受接收类型影响 |
通过一个示例程序来补充下细节
main.m
View Code1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 4 int main(int argc, const char * argv[]) { 5 @autoreleasepool { 6 7 Person *p = [[Person alloc] init]; 8 NSMutableString *s = [NSMutableString stringWithFormat:@"汉三"];//对可变字符串进行操作,地址不会变化,改变的是内容。对不可变字符串的重新赋值,地址内容都会改变。 9 10 p.name = s;// 11 NSLog(@"%p,%p",p.name,s);//打印:0x100114990,0x100114a80 12 Person *p1 = [p mutableCopy];//p属于Person类对象,[]内调用方法必须在该类中存在该方法的协议和实现 //此处使用:Person *p1 = [p mutableCopy]; 为了示例! 13 NSLog(@"%@,%@",p1,p); 14 [s setString:@"王五"]; 15 p1.name = s; 16 NSLog(@"%@,%@,%p,%p",p,p1,p1.name,s);//如果不用copy,对象属性的值会一直跟着变 17 //打印 :0x100300160,0x100114a80 18 } 19 return 0; 20 }
Person.h
View Code1 //如果自定义类想要实现拷贝操作,首先需要遵循NSCopying和NSMutableCopying协议, 2 3 #import<Foundation/Foundation.h> 4 5 @interface Person :NSObject<NSCopying,NSMutableCopying>//协议不能少 6 7 @property (nonatomic,copy)NSString *name;//NSCopy拷贝出的结果是不可变对象 8 9 10 @end
Person.m
View Code1 #import"Person.h" 2 @implementation Person 3 4 -( 5 -(NSString *)description{ 6 7 return_name; 8 } 9 10 } 11 12 //如果直接return self,则是浅拷贝,如果使用alloc,则是深拷贝 13 14 -(id)copyWithZone:(NSZone *)zone{ 15 Person *p = [PersonallocWithZone:zone]; 16 17 // p.name = [self.name copy]; 18 return p; 19 20 } 21 } 22 23 24 //如果直接return self,则是浅拷贝,如果使用alloc,则是深拷贝 25 26 -(id)mutableCopyWithZone:(NSZone *)zone{ 27 28 Person *p = [PersonallocWithZone:zone]; 29 30 // p.name = [self.name copy]; 31 return p; 32 33 } 34 } 35 @end