assign,copy,retain之间的区别

copy: 建立一个索引计数为1的对象,然后释放旧对象
retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1

Copy其实是建立了一个相同的对象,而retain不是:
比如一个NSString对象,地址为0×1111,内容为@”STR”
Copy到另外一个NSString之后,地址为0×2222,内容相同,新的对象retain为1,旧有对象没有变化
retain到另外一个NSString之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1
也就是说,retain是指针拷贝,copy是内容拷贝。
一般情况下:
使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等) 
使用copy: 对NSString 

使用retain: 对其他NSObject和其子类 


举个例子:
NSString *str = [[NSString alloc] initWithString:@'abc'];
上面一段代码会执行以下两个动作:
1 在堆上分配一段内存用来存储@'abc' ,比如:内存地址为0X1111 内容为 'abc'
2 在栈上分配一段内存用来存储str,比如:地址为0XAAAA 内容自然为0X1111

下面分别看下(assign,retain,copy):
1.assign的情况:NSString *newStr = [str assign];
此时newStr和str完全相同,地址都是0XAAAA ,内容为0X1111 ,即newStr只是str的别名,对任何一个操作就等于对另一个操作。因此retainCount不需要增加.
2.retain的情况:NSString * newStr = [str retain];
此时newStr的地址不再为0XAAAA,可能为0XAABB,但是内容依然为0X1111.因此newStr和str都可以管理'abc'所在的内存。因此 retainCount需要增加1.
3.copy的情况:NSString * newStr = [str copy];
此时会在堆上重新开辟一段内存存放@'abc',比如0X1122,内容为@'abc,同时会在栈上为newStr分配空间,比如地址:0XAACC,内容为0X1122,因此retainCount增加1供newStr来管理0X1122这段内存.


3、示例:环境是在不选择ARC的环境下

新建Person类,使他继承与NSObject,在.m文件中实现dealloc方法:
[cpp]  view plain copy
  1. - (void) dealloc    
  2. {    
  3.     NSLog (@"dealloc called. Bye Bye.");    
  4.     [super dealloc];    
  5.       
  6. }   
在引用计数为0时,这个方法就会被调用,证明这个对象被销毁。

创建一个对象,打印它的引用计数
[cpp]  view plain copy
  1. Person *person = [[Person alloc] init];  
  2.   
  3. NSLog(@"对象person的retainCount: %d", [person retainCount]);  

对象personretainCount: 1

我们增加1

[cpp]  view plain copy
  1. Person *person = [[Person alloc] init];  
  2.  NSLog(@"对象person的retainCount: %d",[person retainCount] );  
  3.  [person retain];  
  4.  NSLog(@"对象person的retainCount: %d", [person retainCount]);  

打印结果:

对象personretainCount: 1

对象personretainCount: 2

和传说的一样,retainCount增加了。可以有在release时,减少到1时就不再减 了

[cpp]  view plain copy
  1. Person *person = [[Person alloc] init];  
  2. NSLog(@"对象person的retainCount: %d",[person retainCount] );  
  3. [person retain];  
  4. NSLog(@"对象person的retainCount: %d", [person retainCount]);  
  5. [person release];  
  6. [person release];  
  7. NSLog(@"对象person的retainCount: %d", [person retainCount]);  
这个代码最后打印出来的retainCount是0吗?打印结果:
[cpp]  view plain copy
  1. 2012-07-05 16:05:29.830 ObjectiveCTest[2847:f803] 对象person的retainCount: 1  
  2. 2012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] 对象person的retainCount: 2  
  3. 2012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] dealloc called. Bye Bye.  
  4. 2012-07-05 16:05:29.832 ObjectiveCTest[2847:f803] 对象person的retainCount: 1  
震惊了,第一次release 时 retainCount减1了 ,再release , d对象的dealloc called了,但是retainCount 还是1.在stackoverflow.com的查了一下,有人说这个retainCount没什么用。。。。可以事实的确如 retainCount是1,对象被干掉了。有人说,要把person = nil。这样retainCount就是0了。试了下,nil的 retainlCount永远是0.这个赋值没有意义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值