美文网首页iOSOCiOS记录篇
@property 关键字的区别详解:assign 与weak、

@property 关键字的区别详解:assign 与weak、

作者: 久林的技术随笔 | 来源:发表于2016-03-01 11:40 被阅读3661次

最近有同学问我关于属性@property()的关键字assign,weak,strong,copy区别,这里总结一下,供大家参考。修饰代理等对象使用weak,修饰NSString、block使用copy,但很少思考为什么?这篇文章将会给大家揭开这层面纱。


1.assign 与weak区别

  • assign适用于基本数据类型,weak是适用于NSObject对象,并且是一个弱引用。
  • assign其实也可以用来修饰对象。那么我们为什么不用它修饰对象呢?因为被assign修饰的对象(一般编译的时候会产生警告:Assigning retained object to unsafe property; object will be released after assignment)在释放之后,指针的地址还是存在的,也就是说指针并没有被置为nil,造成野指针。对象一般分配在堆上的某块内存,如果在后续的内存分配中,刚好分到了这块地址,程序就会崩溃掉。
  • 那为什么可以用assign修饰基本数据类型?因为基础数据类型一般分配在栈上,栈的内存会由系统自己自动处理,不会造成野指针。

weak修饰的对象在释放之后,指针地址会被置为nil。所以现在一般弱引用就是用weak。weak使用场景:

  • 在ARC下,在有可能出现循环引用的时候,往往要通过让其中一端使用weak来解决,比如: delegate代理属性,通常就会声明为weak。
  • 自身已经对它进行一次强引用,没有必要再强引用一次时也会使用weak。比如:自定义 IBOutlet控件属性一般也使用weak,当然也可以使用strong。

2.strong 与copy的区别

  • strong 与copy都会使引用计数加1,但strong是两个指针指向同一个内存地址,copy会在内存里拷贝一份对象,两个指针指向不同的内存地址

3.__block与__weak的区别

  • __block是用来修饰一个变量,这个变量就可以在block中被修改

    __block:使用 __block修饰的变量在block代码块中会被retain(ARC下会retain,MRC下不会retain)

  • __weak:使用__weak修饰的变量不会在block代码块中被retain
    同时,在ARC下,要避免block出现循环引用 __weak typedof(self)weakSelf = self;

4.1 block变量定义时为什么用copy?block是放在哪里的?

  • block本身是像对象一样可以retain,和release。但是,block在创建的时候,它的内存是分配在栈(stack)上,可能被随时回收,而不是在堆(heap)上。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。通过copy可以把block拷贝(copy)到堆,保证block的声明域外使用。

特别需要注意的地方就是在把block放到集合类当中去的时候,如果直接把生成的block放入到集合类中,是无法在其他地方使用block,必须要对block进行copy。

[array addObject:[[^{
    NSLog(@"hello!");
} copy] autorelease]];

4.2 block 为什么不用strong?

  • block如果用到了self,就会retain self,如果是strong的话,就造成了循环引用

官方文档:You should specify copy as the property attribute, because a block needs to be copied to keep track of its captured state outside of the original scope. This isn’t something you need to worry about when using Automatic Reference Counting, as it will happen automatically, but it’s best practice for the property attribute to show the resultant behavior

本文全属个人见解,如果您认为说法不正确或者哪里有错误的地方,请在评论中留言或者使用以下联系方式,笔者会在第一时间修正!!!

联系方式:QQ:983202699

关注微博私信:http://weibo.com/490jiulin/home?wvr=5

相关文章

网友评论

  • 奋斗的蝼蚁:copy会在内存里拷贝一份对象,两个指针指向不同的内存地址, 这个说法有问题,copy 对不可变的集合拷贝,是指针拷贝。
  • RFeng:@什么的黑夜 copy会产生新地址,也不完全对,block用copy和strong在ARC,看起来是一样的,在MRC不一样,ARC,在=的时候会进行blockcopy,所以再ARC中不管怎么都是先copy再饮用计数加一
  • 瑛伟达:不错,支持一下
  • __weakcoder:block的循环引用并不是strong导致的…在ARC环境下,系统底层也会做一次copy操作使block从栈区复制一块内存空间到堆区…所以strong和copy在对block的修饰上是没有本质区别的,只不过copy操作效率高而已:blush:,这是我的理解 :smile:
    潸何吊:@__weakcoder 我记着arc环境下并不是每次都会做一次copy操作。当block赋值给堆上的block时 或者作为返回值 或者赋值给__strong标记的id或者Block类型变量时 系统才会隐式得进行copy操作
    久林的技术随笔:@__weakcoder多谢指点,strong和copy在对block的修饰理解,确有偏差。 strong和copy在对block的修饰上是没有本质区别 :+1:
  • 5cfaa4a760b2:讲的不错,mark下

本文标题:@property 关键字的区别详解:assign 与weak、

本文链接:https://www.haomeiwen.com/subject/wlogkttx.html