assign,copy,retain的解释

来源:互联网 发布:中国汽车发展历史 知乎 编辑:程序博客网 时间:2024/05/17 01:27

原文地址:http://my.oschina.net/openlab/blog/89354

举个例子:

    NSString *houseOfMM = [[NSString allocinitWithString:'装梵几的三室两厅'];  

上面一段代码会执行以下两个动作:  
1 在堆上分配一段内存用来存储@' 装梵几的三室两厅 ' ,比如:内存地址为 0X1111  内容为 ' 装梵几的三室两厅' ,  
2 在栈上分配一段内存用来存储 houseForWife ,比如:地址为 0XAAAA  内容自然为 0X1111    


下面分别看下(assign,retain,copy):  
1.assign的情况: NSString  * myHouse  = [ houseOfMM   assign ];  
此时 myHouse  houseOfMM 完全相同,地址都是 0XAAAA  ,内容为 0X1111  ,即 myHouse 只是 houseOfMM 的别名,对任何一个操作就等于对另一个操作。因此 retainCount 不需要增加.(同进同出,关系好,一把钥匙,给我拿着)  
2.retain的情况: NSString  *  myHouse  = [ houseOfMM   retain ];  
此时 myHouse 的地址不再为 0XAAAA ,可能为 0XAABB ,但是内容依然为 0X1111 .因此 myHouse  houseOfMM都可以管理' 装梵几的三室两厅 '所在的内存。因此  retainCount 需要增加1.(有些独立,各自进出,两把钥匙)  
3.copy的情况: NSString  *  myHouse  = [ houseOfMM   copy ];  

此时会在堆上重新开辟一段内存存放@'装梵几的三室两厅',比如0X1122,内容为@'装梵几的三室两厅',同时会在栈上为myHouse分配空间,比如地址:0XAACC,内容为0X1122,因此retainCount增加1供myHouse来管理0X1122这段内存.(两套@'装梵几的三室两厅',条件好,分居了,房子一人一套,所以钥匙一人一把。) 



什么时候用assign,当然是破房子,简装的房子拉
基础类型(简单类型,原子类型):NSInteger,CGPoint,CGFloat,C数据类型(int,float,double,char等)


什么时候用copy
含有可深拷贝的mutable子类的类,如NSArrayNSSetNSDictionaryNSData的,NSCharacterSetNSIndexSetNSString
(可深度拷贝的房子)
但是NSMutableArray这样的不可以,Mutable的不能用copy,不然初始化会有问题。切记

什么时候用retain
其他NSObject和其子类对象好嘛 (大多数)

来源于:http://zhidao.baidu.com/link?url=ghacWu7Us0aPRA7PCjh7AsUbU-j8tguVDMda45WOn19_DfzdbWUwi432umsM3OjtpoLTVo_cQf1BTPPot5WOht00lBBfDjVl78qYeWll-ia

copy:建立一个索引计数为1的对象,然后释放旧对象

@property(nonatomic,assign)NSString *title;

什么是retain,assgin,copy之间的区别?

assign:简单赋值不更改索引计数(reference count)。

copy:建立一个索引计数为1的对象,然后释放旧对象。

retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1
  retain的实际语法为:

- (void)setName:(NSString *)newName {
  if (name != newName) {
  [name release];
  name = [newName retain];
  // name’s retain count has been bumped up by 1
  }
  }
  说了那么麻烦,其实接下来的话最重要:

  
  使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)
  使用copy: 对NSString
  使用retain: 对其他NSObject和其子类
  nonatomic关键字:

  atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。


再转一篇:http://bbs.itheima.com/thread-145753-1-1.html

记得看李明杰老师的视频,老师说过,凡是nsstring,就用copy,定义一个模型对象,就用strong,只是赋值的,例如int、double、char 以及CGRect类似的就用assign。
自己的笔记如下~
这些关键字基本上是针对属性的set方法。
当用copy时,set方法会先release旧值,再copy一个新的对象,reference count 为1(减少了对上下文的依赖);当用assign,直接赋值,无retain操作。当用retain,release旧值,retain新值;


而strong与weak的区别
strong类似于retain,会将对象的引用计数器+1,分配内存地址。
weak类似于指针,只是单纯的指向某个地址,但是本身并未分配内存地址。当指向的地址被销毁时,该指针会自动nil。
例子:
  1.    @synthesize string1;   
  2.    @synthesize string2;  

再来猜一下,下面输出是什么? 



    1.    self.string1 = [[NSString alloc] initWithUTF8String:"string 1"];   
    2.    self.string2 = self.string1;   
    3.    self.string1 = nil;  
    4.    NSLog(@"String 2 = %@", self.string2);  


结果是:String 2 = null

分析一下,由于self.string1与self.string2指向同一地址,且string2没有retain内存地址,而 self.string1=nil释放了内存,所以string1为nil。声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为 nil。这样的好处能有效的防止野指针。在c/c++开发过程中,指针的空间释放了后,都要将指针赋为NULL. 在这儿用weak关键字做了这一步。


0 0