测试代码
NSString *iStr = @"lixue1";
NSString *cpStr = [iStr copy];
NSLog(@"源不可变对象地址:%p 内容%@",iStr,iStr);
NSLog(@"copy出来的对象地址:%p 内容%@",cpStr,cpStr);
NSLog(@"源对象和copy出来的对象地址是否相同: %d",iStr==cpStr?1:0);
NSLog(@"-----------------------------------------");
NSLog(@"对源不可变对象重新赋值");
NSLog(@"-----------------------------------------");
iStr = @"lixue2";//iStr新分配内存空间,cpStr指向原来的内存空间
NSLog(@"源不可变对象地址:%p 内容%@",iStr,iStr);
NSLog(@"copy出来的对象地址:%p 内容%@",cpStr,cpStr);
NSLog(@"源对象和copy出来的对象地址是否相同: %d",iStr==cpStr?1:0);
对非容器类不可变对象copy
1. copy之后内存地址相同,说明没有产生新的对象,是浅拷贝,指针拷贝,两个指针指向同一块内存。(因为copy出来的对象时不可变的,源对象也不可变,如果再申请一块内存浪费空间,所以苹果做了优化)
2. 对指向对象的源指针重新赋值,会新分配一块新的内存空间,剩下的那个还是指向原来的内存空间,所以是完全独立的两份内存,各自的修改不会对对方产生影响
测试代码
NSMutableString *mStr = [[NSMutableString alloc]initWithString:@"lixue"];
NSMutableString *str = [mStr copy];
NSLog(@"源可变对象地址:%p 内容%@",mStr,mStr);
NSLog(@"copy出来的对象地址:%p 内容%@",str,str);
NSLog(@"源对象和copy出来的对象地址是否相同: %d",mStr==str?1:0);
// [str appendString:@" hello"];
对非容器类可变对象copy
1. copy之后内存地址发生改变,说明产生了新的对象,是深拷贝
2. 修改copy出来的对象的值,编译时没有报错,运行时崩溃,找不到方法吗,说明copy出来的对象不可以修改(oc的运行时特性决定了编译时可以调用任何对象的任何方法,编译时是声明的类型,也就是NSMutableString,运行时才会决定对象的真实类型是NSString,NSString是NSMutableString的父类,父类中不一定有子类的方法,所以当查找的时候没有找到,程序崩溃)
测试代码
NSString *iStr = @"lixue1";
NSMutableString *mStr = [iStr mutableCopy];
NSLog(@"源不可变对象的地址:%p 内容%@",iStr,iStr);
NSLog(@"mutableCopy出来对象地址:%p 内容%@",mStr,mStr);
NSLog(@"源对象和mutableCopy出来的对象地址是否相同: %d",iStr == mStr?1:0);
NSLog(@"-----------------------------------------");
NSLog(@"修改mutableCopy出来的对象的值的值");
NSLog(@"-----------------------------------------");
[mStr appendString:@" hello"];
NSLog(@"源不可变对象的地址:%p 内容%@",iStr,iStr);
NSLog(@"mutableCopy出来对象地址:%p 内容%@",mStr,mStr);
NSLog(@"源对象和mutableCopy出来的对象地址是否相同: %d",iStr == mStr?1:0);
对不可变非容器类对象mutableCopy
1. mutableCopy之后产生了新对象,是深拷贝
2. 修改新对象的值,修改成功,并且对源对象的值没有影响,所以mutableCopy的对象可以修改
测试代码
NSMutableString *mStr = [[NSMutableString alloc]initWithString:@"lixue"];
NSMutableString *mcpStr = [mStr mutableCopy];
NSLog(@"源可变对象的地址:%p 内容%@",mStr,mStr);
NSLog(@"mutableCopy出来的对象的地址:%p 内容%@",mcpStr,mcpStr);
NSLog(@"源对象和mutableCopy出来的对象地址是否相同: NSLog(@"-----------------------------------------");
NSLog(@"修改mutableCopy出来的对象的值");
NSLog(@"-----------------------------------------");
[mStr appendString:@" hello"];
NSLog(@"源可变对象的地址:%p 内容%@",mStr,mStr);
NSLog(@"mutableCopy出来的对象的地址:%p 内容%@",mcpStr,mcpStr);
NSLog(@"源对象和mutableCopy出来的对象地址是否相同 %d",mcpStr == mStr?1:0);
对可变非容器类对象mutableCopy
1. mutableCopy之后产生了新对象,是深拷贝
2. 修改新对象的值,修改成功,对原来对象没影响,说明mutableCopy出来的对象可以修改
- 对不可变对象copy,是浅拷贝,copy出来对象不可变
- 对可变对象copy,是深拷贝,拷贝出来的对象不可变
- 对不可变对象mutableCopy,是深拷贝,新对象可变
- 对可变对象mutableCopy,是深拷贝,新对象可变
测试代码
NSArray *iarr = @[[NSMutableString stringWithString:@"hello "],@"2",@"3"];
NSArray *cpArr = [iarr copy];
NSLog(@"源容器类对象地址:%p 内容:%@",iarr,iarr);
NSLog(@"copy出来的容器类对象的地址:%p 内容:%@",cpArr,cpArr);
NSLog(@"源容器类对象和copy出来的容器类对象的地址是否相等: %d",iarr==cpArr?1:0);
NSLog(@"源容器类对象中的元素的地址:%p 内容:%@",iarr[0],iarr[0]);
NSLog(@"copy出来的容器类对象中的元素的地址:%p 内容:%@",cpArr[0],cpArr[0]);
NSLog(@"源容器类对象中的元素的地址和copy出来的容器类对象中的元素的地址是否相等: %d",iarr[0]==cpArr[0]?1:0);
NSLog(@"-----------------------------------------");
NSLog(@"给源容器类对象重新赋值");
NSLog(@"-----------------------------------------");
iarr = @[[NSMutableString stringWithString:@"444 "],@"5",@"6"];//iarr新分配内存空间,cpArr指向原来的内存空间
NSLog(@"源容器类对象地址:%p 内容:%@",iarr,iarr);
NSLog(@"copy出来的容器类对象的地址:%p 内容:%@",cpArr,cpArr);
NSLog(@"源容器类对象和copy出来的容器类对象的地址是否相等: %d",iarr==cpArr?1:0);
NSLog(@"源容器类对象中的元素的地址:%p 内容:%@",iarr[0],iarr[0]);
NSLog(@"copy出来的容器类对象中的元素的地址:%p 内容:%@",cpArr[0],cpArr[0]);
NSLog(@"源容器类对象中的元素的地址和copy出来的容器类对象中的元素的地址是否相等: %d",iarr[0]==cpArr[0]?1:0);
测试代码
NSMutableArray *marr = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"hello "],@"2", nil];
NSMutableArray *cpmarr = [marr copy];
NSLog(@"源可变容器类对象地址:%p 内容:%@",marr,marr);
NSLog(@"copy出来的对象的地址:%p 内容:%@",cpmarr,cpmarr);
NSLog(@"源可变容器类对象地址和copy出来的对象的地址是否相等: %d",marr ==cpmarr?1:0);
NSLog(@"源可变容器类对象中的元素的地址:%p 内容:%@",marr[0],marr[0]);
NSLog(@"copy出来的对象中的元素的地址:%p 内容:%@",cpmarr[0],cpmarr[0]);
NSLog(@"源可变容器类对象中元素的地址和copy出来的容器类对象的元素的地址是否相等: %d",[marr[0] isEqual:cpmarr[0]]?1:0);
[cpmarr[0] appendString:@"lixue"];
NSLog(@"-----------------------------------------");
NSLog(@"修改copy出来的容器类对象的第0号元素的值");
NSLog(@"-----------------------------------------");
NSLog(@"源可变容器类对象地址:%p 内容:%@",marr,marr);
NSLog(@"copy出来的对象的地址:%p 内容:%@",cpmarr,cpmarr);
NSLog(@"源可变容器类对象地址和copy出来的对象的地址是否相等: %d",marr ==cpmarr?1:0);
NSLog(@"源可变容器类对象中的元素的地址:%p 内容:%@",marr[0],marr[0]);
NSLog(@"copy出来的对象中的元素的地址:%p 内容:%@",cpmarr[0],cpmarr[0]);
NSLog(@"源可变容器类对象中元素的地址和copy出来的容器类对象的元素的地址是否相等: %d",[marr[0] isEqual:cpmarr[0]]?1:0);
// [cpmarr addObject:@"88"];
测试代码
NSArray *iarr = @[[NSMutableString stringWithString:@"hello "],@"2",@"3"];
NSMutableArray *mcpArr = [iarr mutableCopy];
NSLog(@"源不可变容器类对象地址:%p 内容:%@",iarr,iarr);
NSLog(@"mutableCopy出来的对像的地址%p 内容:%@",mcpArr,mcpArr);
NSLog(@"源不可变容器类对象的地址和mutableCopy出来的对象的地址是否相同: %d",iarr ==mcpArr?1:0);
NSLog(@"源不可变容器类对象中的元素的地址:%p 内容:%@",iarr[0],iarr[0]);
NSLog(@"mutableCopy出来的容器对象中的元素的地址:%p 内容:%@",mcpArr[0],mcpArr[0]);
NSLog(@"源不可变容器类对象中元素的地址和mutableCopy出来的容器中元素的地址是否相同:%d",iarr[0] ==mcpArr[0]?1:0);
NSLog(@"-----------------------------------------");
NSLog(@"修改mutableCopy出来的容器类对象的第0号元素的值");
NSLog(@"-----------------------------------------");
[mcpArr[0] appendString:@"lixue"];
NSLog(@"源不可变容器类对象地址:%p 内容:%@",iarr,iarr);
NSLog(@"mutableCopy出来的对像的地址%p 内容:%@",mcpArr,mcpArr);
NSLog(@"源不可变容器类对象的地址和mutableCopy出来的对象的地址是否相同: %d",iarr ==mcpArr?1:0);
NSLog(@"源不可变容器类对象中的元素的地址:%p 内容:%@",iarr[0],iarr[0]);
NSLog(@"mutableCopy出来的容器对象中的元素的地址:%p 内容:%@",mcpArr[0],mcpArr[0]);
NSLog(@"源不可变容器类对象中元素的地址和mutableCopy出来的容器中元素的地址是否相同:%d",iarr[0] ==mcpArr[0]?1:0);
测试代码
NSMutableArray *marr = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"hello "],@"2", nil];
NSMutableArray *mcpmarr = [marr mutableCopy];
NSLog(@"源可变容器类对象地址:%p 内容:%@",marr,marr);
NSLog(@"mutableCopy出来的对像的地址%p 内容:
NSLog(@"源可变容器类对象的地址和mutableCopy出来的对象的地址是否相同: %d",marr ==mcpmarr?1:0);
NSLog(@"源可变容器类对象中的元素的地址:%p 内容:%@",marr[0],marr[0]);
NSLog(@"mutableCopy出来的容器对象中的元素的地址:%p 内容:%@",mcpmarr[0],mcpmarr[0]);
NSLog(@"源可变容器类对象中元素的地址和mutableCopy出来的容器中元素的地址是否相同: %d",marr[0]==mcpmarr[0]?1:0);
NSLog(@"-----------------------------------------");
NSLog(@"修改mutableCopy出来的容器类对象的第0号元素的值");
NSLog(@"-----------------------------------------");
[mcpmarr[0] appendString:@"lixue"];
NSLog(@"源可变容器类对象地址:%p 内容:%@",marr,marr);
NSLog(@"mutableCopy出来的对像的地址%p 内容:%@",mcpmarr,mcpmarr);
NSLog(@"源可变容器类对象的地址和mutableCopy出来的对象的地址是否相同: %d",marr ==mcpmarr?1:0);
NSLog(@"源可变容器类对象中的元素的地址:%p 内容:%@",marr[0],marr[0]);
NSLog(@"mutableCopy出来的容器对象中的元素的地址:%p 内容:%@",mcpmarr[0],mcpmarr[0]);
NSLog(@"源可变容器类对象中元素的地址和mutableCopy出来的容器中元素的地址是否相同: %d",marr[0]==mcpmarr[0]?1:0);
-(id)copyWithZone:(NSZone *)zone{
Person * p = [[Person alloc]init];
p.name = self.name;
return p;
}
Person *p = [[Person alloc]init];
p.name = @"lixue";
Person *cp = [p copy];
NSLog(@"源自定义对象地址:%p 自定义对象的属性地址:%p 内容%@",p,p.name,p.name);
NSLog(@"copy出来的自定义对象地址:copy出来的自定义对象地属性址:%p %p 内容%@",cp,cp.name,cp.name);
这个没想出来有什么用?