关于属性weak strong copy 那些事

这些关键字基本上是针对属性的set方法。

  1. strong:release旧值,retain新值,新值的retainCount+1;适用于基本的OC对象(除NSString外)
  2. assign:直接赋值,不更改retainCount。适用简单数据类型
  3. weak:同assign,但是区别与它的有一点,当用weak修饰的对象被别的变量释放,那么weak修饰的变量会被自动设置为nil,这样可以有效地防止崩溃。常用于解决循环引用。
  4. copy:set方法会先release旧值,再copy一个新的对象,reference count 为1;retain和copy的区别在于retain是对对象的引用计数+1,copy是创建一个新的对象。适用于block和NSString。
  5. unsafe_unretained:个人认为它与assign是等价的。
  6. strong、weak这两个关键词是在ARC时引入的。strong基本取代了MRC中的retain。至于strong和retain,究竟一不一样。网上很多人问,能讲清楚的没几个。不过我看过几个,说的是在修饰Block时,使用strong和retain会有截然不同的效果。strong会等于copy,而retain竟然等于assign!

闲言少叙,直接上代码


@interface Person : NSObject
@property (nonatomic, strong) NSObject *obj1;
@property (nonatomic, strong) NSObject *obj2;
@end


- (void)demo {
    Person *p = [Person new];
    p.obj1 = [NSObject new] ;
    p.obj2 = p.obj1;
    p.obj1 = nil;
    NSLog(@"obj 1 = %@", p.obj1);
    NSLog(@"obj 2 = %@", p.obj2);
}

【分析】

  1. Person *p = [Person new]; //开辟一块内存空间,指针P指向该内存空间,
  2. 经过p.obj2 = p.obj1;p.obj1与p.p.obj2指向同一地址,所以[NSObject new]所对应的retainCount为2
  3. 经过p.obj1 = nil;p.obj1指针指向NULL,[NSObject new]所对应的retainCount变为1,即仍有一个强指针指向(p.obj2)

【结果】
2017-04-26 16:29:10.740 08-weak&retain[4808:1281804] obj 1 = (null)
2017-04-26 16:29:10.740 08-weak&retain[4808:1281804] obj 2 =

如果将上述的属性obj2改成weak


@interface Person : NSObject
@property (nonatomic, strong) NSObject *obj1;
@property (nonatomic, weak) NSObject *obj2;
@end

【结果】

2017-04-27 14:35:12.368 08-weak&retain[5805:1081448] obj 1 = (null)
2017-04-27 14:35:12.368 08-weak&retain[5805:1081448] obj 2 = (null)

【分析】

同样经过p.obj2 = p.obj1;p.obj1因为是strong所以指向[NSObject new]所对应的内存空间,但是p.obj2仅仅做了赋值,所以[NSObject new]所对应的retainCount仍为1
经过p.obj1 = nil;p.obj1指针指向NULL,[NSObject new]所对应的retainCount变为0,被内存回收。weak修饰的变量p.obj2被自动设置为nil

同样如果再把属性obj2改成unsafe_unretained
会直接crash在NSLog(@"obj 2 = %@", p.obj2);这句代码上,原因是因为他没有像weak一样置为nil。

你可能感兴趣的:(关于属性weak strong copy 那些事)