什么是深拷贝和浅拷贝
深复制:直接拷贝生成一个新对象,改变原对象的属性不会影响新的对象,在内存中出现了两个独立的对象本身。
浅拷贝:并不拷贝对象本身,只是对指向对象的指针进行拷贝,改变原对象的属性会影响新的对象,内存中本质上还是一个对象。
非容器类的深拷贝和浅拷贝
不可变对象的拷贝
//[str1 mutableCopy];生成的是一个可变对象
//因为都是不可变字符串,创建方式并不影响拷贝方式。
NSString *str1 = @"这是string";
NSString *str2 = [str1 copy];
NSString *str3 = [str1 mutableCopy];
NSMutableString *str4 = [str1 copy];
NSMutableString *str5 = [str1 mutableCopy];
NSLog(@"str1 = %p str2 = %p",str1,str2);
NSLog(@"str1 = %p str3 = %p",str1,str3);
NSLog(@"str1 = %p str4 = %p",str1,str4);
NSLog(@"str1 = %p str5 = %p",str1,str5);
/*
str1 = 0x10a812070 str2 = 0x10a812070
str1 = 0x10a812070 str3 = 0x60000139fbd0
str1 = 0x10a812070 str4 = 0x10a812070
str1 = 0x10a812070 str5 = 0x60000139e1c0
*/
对与非容器不可变对象,copy是浅拷贝,mutableCopy是深拷贝
不可变对象copy后返回的对象是不可变的,mutableCopy后返回的对象是可变的。
可变对象的拷贝
NSMutableString *str1 = [[NSMutableString alloc]initWithString:@"这是一个string"];
NSString *str2 = [str1 copy];
NSString *str3 = [str1 mutableCopy];
NSMutableString *str4 = [str1 copy];
NSMutableString *str5 = [str1 mutableCopy];
NSLog(@"str1 = %p str2 = %p",str1,str2);
NSLog(@"str1 = %p str3 = %p",str1,str3);
NSLog(@"str1 = %p str4 = %p",str1,str4);
NSLog(@"str1 = %p str5 = %p",str1,str5);
/*
str1 = 0x600001085bf0 str2 = 0x600001086040
str1 = 0x600001085bf0 str3 = 0x600001085a70
str1 = 0x600001085bf0 str4 = 0x600001085d10
str1 = 0x600001085bf0 str5 = 0x600001085c20
*/
对与非容器可变对象,copy,mutableCopy都是深拷贝
可变对象copy后返回的对象是不可变的,mutableCopy后返回的对象是可变的。
容器类的深拷贝和浅拷贝
不可变对象的拷贝
NSArray *arr1 = @[@"1",@"2",@"3"];
NSArray *arr2 = [arr1 copy];
NSArray *arr3 = [arr1 mutableCopy];
NSMutableArray *arr4= [arr1 copy];
NSMutableArray *arr5 = [arr1 mutableCopy];
NSLog(@"arr1 = %p arr2 = %p",arr1,arr2);
NSLog(@"arr1 = %p arr3 = %p",arr1,arr3);
NSLog(@"arr1 = %p arr4 = %p",arr1,arr4);
NSLog(@"arr1 = %p arr5 = %p",arr1,arr5);
/*
arr1 = 0x600002e6ad60 arr2 = 0x600002e6ad60
arr1 = 0x600002e6ad60 arr3 = 0x600002e6a040
arr1 = 0x600002e6ad60 arr4 = 0x600002e6ad60
arr1 = 0x600002e6ad60 arr5 = 0x600002e69ef0
*/
对与容器不可变对象,copy是浅拷贝,mutableCopy是深拷贝
不可变对象copy后返回的对象是不可变的,mutableCopy后返回的对象是可变的。
可变对象的拷贝
NSMutableArray *arr1 = [[NSMutableArray alloc]initWithArray:@[@"1",@"2",@"3"]];
NSArray *arr2 = [arr1 copy];
NSArray *arr3 = [arr1 mutableCopy];
NSMutableArray *arr4= [arr1 copy];
NSMutableArray *arr5 = [arr1 mutableCopy];
NSLog(@"arr1 = %p arr2 = %p",arr1,arr2);
NSLog(@"arr1 = %p arr3 = %p",arr1,arr3);
NSLog(@"arr1 = %p arr4 = %p",arr1,arr4);
NSLog(@"arr1 = %p arr5 = %p",arr1,arr5);
/*
arr1 = 0x6000002df810 arr2 = 0x6000002df300
arr1 = 0x6000002df810 arr3 = 0x6000002dd0e0
arr1 = 0x6000002df810 arr4 = 0x6000002df690
arr1 = 0x6000002df810 arr5 = 0x6000002dd5c0
*/
对与容器可变对象,copy,mutableCopy都是深拷贝
可变对象copy后返回的对象是不可变的,mutableCopy后返回的对象是可变的。
综上所述,对与不可变对象,copy是浅拷贝,mutableCopy是深拷贝。对与可变对象,copy,mutableCopy都是深拷贝。
怎么使用copy关键字?
NSString,NSArray,NSDictionary等经常使用到copy,
是因为他们对应的可变类型NSMutableString,NSMutableArray,NSMutableDictionary,它们之间可以进行赋值操作,为确保对象中的值不能随意变动,应该在设置新值时拷贝一份。
block 也使用copy。
@property(nonatomic,copy)NSMutableArray *array;这么写会出现什么问题?
在添加,删除,修改数组内元素时,程序会因为找到不到对应的方法而奔溃,应为copy就是复制一个不可变的NSArray对象