属性修饰符

ARC 对象默认属性修饰符:@property (atomatic, readwrite, assign, strong) id object;

weak  assign区别:

举个栗子��:

@property (nonatomic,strong)id strongObject;

@property (nonatomic,assign)id assignPoint;

@property (nonatomic,weak)id weakPoint;

***************************** ****************************** * ****************************** ******************************

    self.strongObject = [[NSObjectalloc]init];

    self.assignPoint = self.strongObject;

    self.weakPoint = self.strongObject;

//    self.strongObject = nil;

    NSLog(@"ASSIGNPOINT : %@ \nWEAKPOINT : %@",self.assignPoint,self.weakPoint);

Console print:

ASSIGNPOINT : <NSObject: 0x7964b000> 

WEAKPOINT : <NSObject: 0x7964b000>

而当注释 //  self.strongObject = nil;被打开后, 可能就会崩溃.(可能不崩溃?因为_strongObject内存可能还没被真正释放,只是引用计数变为0了,可以嵌套一个循环多操作几次就会崩溃了)

原因:首先,assign和weak不会对指向的内存做retain操作,所以当它们指向的内存引用计数为0时就会被释放。assign和weak的区别是,当指向的内存被释放后,weak指向的内存会自动置为nil,访问nil指针不会崩溃,而assign指向的内存不会自动置为nil(野指针),当访问野指针时就会导致崩溃。

copy strong 区别:

copy修饰的对象不会对引用的对象造成影响,strong修饰的对象修改会对引用的对象造成影响。

举个栗子...

@property (nonatomatic, strong) NSArray * array1;

@property (nonatomatic, copy) NSAarry *array2;

************************************************************************************************************************

    NSMutableArray *array = [[NSArrayarrayWithObject:@"yyyycccczzzz"]mutableCopy];

    self.array1 = array;

    self.array2 = array;

    [array addObject:@"so strong!"];

    NSLog(@"\nARRAY1 CONTENT ----- %@\nARRAY2 CONTENT ----- %@",self.array1,self.array2);

Console print:

ARRAY1 CONTENT ----- (

    yyyycccczzzz,

    "so strong!"

)

ARRAY2 CONTENT ----- (

    yyyycccczzzz

)

什么原因导致的这种结果?分析一下这两种修饰符修饰的对象的setter方法都做了什么:

array1的setter方法:_array1 先执行一次release操作,然后array执行一次retain操作,最后一步操作_array1 = array 。

array2的setter方法:  _array2  先执行一次release操作,  然后array执行一次copy操作,  最后一步操作_array1 = array 。

很显然_array1和array指向了同一个空间,所以array变化了,_array1也会跟着变化;_array2是copy修饰的,copy会开辟新的空间,_array2指向的就是array copy的新空间和array指向的不是同一块空间,所以array怎么变化都不会影响_array2;


修饰数组时选择copy还是strong?

修饰可变数组时用strong,修饰不可变数组时用copy。

再举个栗子...

@property (nonatomic,copy)NSMutableArray *array1;

************************************************************************************************************************

   self.array1 = [NSMutableArrayarrayWithObject:@"ycz"];

   [self.array1addObject:@"so strong!"];


run ——> crash!

 Console print:

2016-08-25 16:19:26.168 MessageForwarding[59042:5124805] -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x79e1e7e0

原因:copy会把可变数组变成不可变数组,不可变数组执行addObject:导致崩溃,所以可变数组要用strong来修饰。


@property (nonatomic,strong)NSMutableArray *array1;

@property (nonatomic,strong)NSArray *array2;

************************************************************************************************************************

    self.array1 = [NSMutableArrayarrayWithObjects:@"ycz",nil];

    self.array2 =self.array1;

    NSLog(@"FIRST ARRAY2 CONTENT:%@\n",self.array2);

    [self.array1addObject:@"so strong!"];

    NSLog(@"SEC ARRAY2 CONTENT:%@\n",self.array2);


 Console print:

 FIRST ARRAY2 CONTENT:(

    ycz

)

 SEC ARRAY2 CONTENT:(

    ycz,

    "so strong!"

)

会发现array1添加了新对象后 NSArray  类型的array2也发生了变化,而在我们工程中NSArray的动态变化是我们不想见到的...所以NSArray不能用strong修饰,要用copy来修饰。


PS:以前一直以为weak修饰的对象出了大括号后会被立即释放,在看了某个大神的一篇blog后发现之前的理解是错的。


按之前的理解断点处str已经被释放了,po出来应该是nil,结果是:


原因是weak修饰的对象是被加到自动释放池释放的,而自动释放池释放时机是依赖runloop的,当结束了当前runloop后自动释放池才会去释放里面的对象(上面的例子也说明viewDidLoad和ViewWillAppear是在同一个runloop里)。

若有错误请帮忙指出,谢谢。

未完待续.....


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值