#4- strong copy assign weak __block __weak

1.assign 与weak区别

assign 常用来修饰 基本数据类型,weak常用来修饰对象对象,且是一个弱引用。

  • 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代码块中会被retain(ARC下会retain,MRC下不会retain)

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

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

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

  • block的循环引用并不是strong导致的…在ARC环境下,系统底层也会做一次copy操作(当block赋值给堆上的block时 或者作为返回值 或者赋值给__strong标记的id或者Block类型变量时 系统才会隐式得进行copy操作)使block从栈区复制一块内存空间到堆区…所以strong和copy在对block的修饰上是没有本质区别的,只不过copy操作效率高而已。

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

block 为什么不用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
5. atomic 和 nonatomic 有什么区别

atomic 和 nonatomic 的区别在于,系统自动生成的 getter/setter 方法不一样。如果你自己写 getter/setter,那 atomic/nonatomic/retain/assign/copy 这些关键字只起提示作用,写不写都一样。参考

  • atomic: 是默认的, 系统生成的 getter/setter 会保证 get、set 操作的完整性,不受其他线程影响。会保证 CPU 能在别的线程来访问这个属性之前,先执行完当前流程,速度不快,因为要保证操作整体完成。

  • nonatomic: 就没有这个保证了。不是默认的,更快,线程不安全,如有两个线程访问同一个属性,会出现无法预料的结果。

不过atomic可并不能保证线程安全。这个属性只能说是 setter 和getter 读/写安全的,但并不是线程安全的。参考

https://www.jianshu.com/p/3e0f12e5faaa

你可能感兴趣的:(#4- strong copy assign weak __block __weak)