深入理解 retain,copy,mutableCopy
来源:互联网 发布:网络交友有哪些弊端 编辑:程序博客网 时间:2024/06/06 01:02
一,retain和copy的区别:
@property(nonatomic,retain)NSString *str ;@property(nonatomic,copy)NSString *str2 ; <span style="color:#ff0000;">NSString</span> *tmp1=[[NSString alloc] initWithFormat:@"tmp1"]; self.str=tmp1; NSLog(@"%@,address:%p,retainCount:%d",tmp1,tmp1,tmp1.retainCount); NSLog(@"%@,address:%p,retainCount:%d",self.str,self.str,self.str.retainCount); [tmp1 release]; <span style="color:#ff0000;">NSString</span> *tmp2=[[NSString alloc] initWithFormat:@"tmp2"]; self.str2=tmp2; NSLog(@"%@,address:%p,retainCount:%d",tmp2,tmp2,tmp2.retainCount); NSLog(@"%@,address:%p,retainCount:%d",self.str2,self.str2,self.str2.retainCount); [tmp2 release];输出结果:
[1619:607] tmp1,address:0xca4d500,retainCount:2
[1619:607] tmp1,address:0xca4d500,retainCount:2
[1619:607] tmp2,address:0xca11360,retainCount:2
[1619:607] tmp2,address:0xca11360,retainCount:2
由以上可以看出,NSString类型的属性,不管是retain还是copy,当用一个NSString 不可变类型变量赋值时,其安全性、内存管理都一样;@property(nonatomic,retain)NSString *str ;@property(nonatomic,copy)NSString *str2 ; <span style="color:#ff0000;">NSMutableString</span> *tmp1=[[NSMutableString alloc] initWithFormat:@"tmp1"]; self.str=tmp1; NSLog(@"%@,address:%p,retainCount:%d",tmp1,tmp1,tmp1.retainCount); NSLog(@"%@,address:%p,retainCount:%d",self.str,self.str,self.str.retainCount); [tmp1 release]; <span style="color:#ff0000;">NSMutableString</span> *tmp2=[[NSMutableString alloc] initWithFormat:@"tmp2"]; self.str2=tmp2; NSLog(@"%@,address:%p,retainCount:%d",tmp2,tmp2,tmp2.retainCount); NSLog(@"%@,address:%p,retainCount:%d",self.str2,self.str2,self.str2.retainCount); [tmp2 release];输出结果:
[1643:607] tmp1,address:0xc8389c0,retainCount:2
[1643:607] tmp1,address:0xc8389c0,retainCount:2
[1643:607] tmp2,address:0xc836500,retainCount:1
[1643:607] tmp2,address:0xc824130,retainCount:1
由以上可以看出,NSString类型的属性,用retain修饰,当用一个NSMutableString 可变类型变量赋值时,其内存地址一样,只有一份拷贝;用copy修饰时,内存地址变了,此时拥有两份拷贝。为了更好的看出区别,我们作如下测试:
例3:
@property(nonatomic,retain)NSString *str ;@property(nonatomic,copy)NSString *str2 ; <span style="color:#ff0000;">NSMutableString</span> *tmp1=[[NSMutableString alloc] initWithFormat:@"tmp1"]; self.str=tmp1; <span style="color:#3333ff;">[tmp1 appendString:@"AAA"];</span> NSLog(@"%@,address:%p,retainCount:%d",tmp1,tmp1,tmp1.retainCount); NSLog(@"%@,address:%p,retainCount:%d",self.str,self.str,self.str.retainCount); [tmp1 release]; <span style="color:#ff0000;">NSMutableString</span> *tmp2=[[NSMutableString alloc] initWithFormat:@"tmp2"]; self.str2=tmp2; <span style="color:#3333ff;">[tmp2 appendString:@"BBB"];</span> NSLog(@"%@,address:%p,retainCount:%d",tmp2,tmp2,tmp2.retainCount); NSLog(@"%@,address:%p,retainCount:%d",self.str2,self.str2,self.str2.retainCount); [tmp2 release];输出结果:
[1673:607] tmp1AAA,address:0xce55930,retainCount:2
[1673:607] tmp1AAA,address:0xce55930,retainCount:2
[1673:607] tmp2BBB,address:0xce55970,retainCount:1
[1673:607] tmp2,address:0xce559b0,retainCount:1
由以上可以看出,当用可变类型变量赋值成员属性后,再对可变类型的变量进行了修改,那么retain修饰的,也同样会被修改;copy修饰的,因为是对象的拷贝,所以,不会同步被外界变量所修改。综合以上实验,可以得出结论,如果为成员变量赋值时,使用的是不可变的变量,那么retain和copy从内存管理上来说,其效果是一样的,没有什么使用的区别。如果使用的是可变变量对属性进行赋值,那么retain修饰的属性值就有可能被修改的可能(这往往不是我们想要的结果),而使用copy修饰的属性值就不会被修改。故:官方的sdk中,NSString 类型都是copy修饰。
建议:NSString 属性,请使用copy修饰。(当然,如果你想让你的属性值跟着变量的变化而变化,那就用retain吧)
二,copy和mutableCopy的区别
NSString *tmp1=[[NSString alloc] initWithFormat:@"tmp1"]; NSString *copy1= [tmp1 copy]; NSMutableString *mutableCopy1=[tmp1 mutableCopy]; NSLog(@"tmp1:%p,copy1:%p,mutableCopy1:%p",tmp1,copy1,mutableCopy1); [tmp1 release]; NSMutableString *tmp2=[[NSMutableString alloc] initWithFormat:@"tmp2"]; NSString *copy2= [tmp2 copy]; NSMutableString *mutableCopy2=[tmp2 mutableCopy]; NSLog(@"tmp2:%p,copy2:%p,mutableCopy2:%p",tmp2,copy2,mutableCopy2); [tmp1 release];输出结果:
[1805:607] tmp1:0xc833dd0,copy1:0xc833dd0,mutableCopy1:0xc833db0
[1805:607] tmp2:0xc826fb0,copy2:0xc835490,mutableCopy2:0xc8354a0
建议:记住一点即可,如果复制的是不可变类型,那么copy并没有开辟新的内存,而是进行了一次浅拷贝。当然了,在实际应用中,copy返回的是不可变对象,mutableCopy返回的是可变对象,除此之外,其他都不影响使用。三、retainCount = -1 的疑惑
NSString *tmp=[[NSString alloc] initWithString:@"aaa"]; //这里等同于: tmp=@"aaa"; NSLog(@"%d",tmp.retainCount); [tmp retain]; NSLog(@"%d",tmp.retainCount); [tmp release]; NSLog(@"%d",tmp.retainCount); _str=tmp; //str为retain修饰的成员属性 _str2=tmp; //str2为copy修饰的成员属性 NSLog(@"%d,%d",_str.retainCount,_str2.retainCount);输出结果:
2016:607] -1
[2016:607] -1
[2016:607] -1
[2016:607] -1,-1
这里,我们可以看到输出结果都为-1,这是因为 @"aaa" 其实是分配在常量存储区,系统不会对齐回收,也不会对齐进行引用计数。四、NSString、NSArray等赋值时注意
NSArray *tmpArray=@[@1,@2]; // tmpArray retainCount =1;
self.array=tmpArray; // 赋值方法1: self.array retainCount =2; 推荐
_array=tmpArray; //赋值方法2: self.array retainCount =1; 不推荐
- 深入理解 retain,copy,mutableCopy
- copy和mutableCopy,retain
- copy,mutableCopy,retain区别
- Copy,mutableCopy和retain的区别的小理解
- copy与retain copy和mutableCopy区别
- copy,mutableCopy 理解
- copy,mutableCopy 理解
- copy mutablecopy 和 retain 的 区别
- 理解assign,copy,retain
- assign copy retain 理解
- retain/assign/strong/weak/copy/mutablecopy/autorelease区别
- iOS开发-retain/assign/strong/weak/copy/mutablecopy/autorelease区别
- ios之关键字retain / copy / mutableCopy 使用技巧
- iOS开发-retain/assign/strong/weak/copy/mutablecopy/autorelease区别
- iOS开发-retain/assign/strong/weak/copy/mutablecopy/autorelease区别
- iOS开发-retain/assign/strong/weak/copy/mutablecopy/autorelease区别
- retain/assign/strong/weak/copy/mutablecopy/autorelease区别
- retain、copy、mutableCopy的区别(深拷贝 浅拷贝)
- 视频:《博物馆3》猴子闹罗宾哭 大表哥客串
- 递归算法
- if 语句会出现的问题
- VS2008下编译linphone3.5.2
- Object C 继承
- 深入理解 retain,copy,mutableCopy
- 在 Eclipse 下利用 gradle 构建系统
- 判断日期在所在年中的位置
- ElasticSearch模块threadpool
- HTML中设置td的字体颜色
- wince系统中自绘button响应WM_LBUTTONUP和WM_LBUTTONDOWN两个消息
- openfilediaolog
- 几个机器学习算法及应用领域相关的中国大牛
- 纯CSS实现IOS开关效果