@property中retain assign copy详解

来源:互联网 发布:知乎 苏享茂事件始末 编辑:程序博客网 时间:2024/05/23 16:09
转载自:http://blog.sina.com.cn/s/blog_b716ca8d0102uy6s.html

说明:看了很多书上的描述,对retain assign 和copy的都是草草描述,没有谈及本质,但是retain assign 和copy却是内存管理的重要内容,所以自己总结了下,本文涉及到了Objective-C内存管理的原则,阅读前需要了解。

retain assign copy在@propeerty中的使用实际上是通过控制set方法进行内存管理。下面详细介绍:

1.retain:

    例如:

        @class Dog

        @property(nonatomic,retain) Dog *dog;

    注:nonatomic与atomic相对应,涉及线程,比较麻烦,这里不做赘述,读者仅需记住,nonatomic相对于atomic来说性能高,而声明属性时一般默认为atomic,故需在此申明nonatomic

这里使用了retain,那么在set方法中,究竟如何体现的呢?

- (void)setDog:(Dog *)dog

{

   if(_dog != dog){          //判断是否需要重新赋值

      [_dog release];        //释放旧引用,计数器-1

      _dog = [dog retain];   //重新赋值,计数器+1

   }

}

2.assign:

   例如:

        @property(nonatomic,assign)int count;

这里使用了assign,那么在set方法中,究竟如何体现的呢?

- (void)setCount:(int)count

{

   _count = count;

}

2.assign:

   例如:

 

        @property(nonatomic,copy)NSString * str;

这里使用了copy,那么在set方法中,究竟如何体现的呢?

- (void)setStr:(NSString *)str

{

 if(_str != str){          //判断是否需要重新赋值

      [_str release];        //释放旧引用,计数器-1

      _str = [str copy];   //重新赋值,使用copy

   }

}

总结:

     1.retain:先release旧值,再retain新值,在上例中_dog与dog最终指向同一快内存区域。

     2.assign:直接赋值,不考虑内存管理。

     3.copy:先release旧值,再copy新值,copy的本质为复制该内存所存储的内容,重新创建一个对象赋给其相同的内容,很明显,在copy这个过程中也发生了一次retain,不过这是个全新的对象。在上例中,_str与str最终指向了不同的内存区域,但其内容一样。

     4.从retain assign copy的特点中我们可以看出:

            retain一般适用于OC中的对象

            assign一般适用于非OC对象,如int等普通类型

            copy一般适用于NSString等不可变的对象,因为是重新创建了对象,并且内容不变,因此不用担心后面的操作会对该属性的值产生影响。

 

copy与retain实例分析:

      假设str为对象p的属性

      @property(nonatomic,copy)NSString *str;

      NSMutableSting *s = [[NSMutableSting alloc] setString:@"hello"];

      p.str = s;   //此时,str的值为@"hello"

      [s appendString:@"world"];   //此时,s的值为"hello world",但是str的值依然为"hello".

     但是如果开始时str的申明为:

    @property(nonatomic,retain)NSString *str;

    那么,在进行完 [s appendString:@"world"]之后,str的值将变为"hello world".因为str与s共用一块内存,内容完全相同,而s是可以改变的,所以s改变后,str也将改变。

 

注:以上皆为个人理解,如有错误,请留言指正,万分感谢。

0 0
原创粉丝点击