assign 和 weak的区别
assign适用于基本数据类型,weak是适用于NSObject对象
assign其实也可以用来修饰对象,那么我们为什么不用它呢?因为被assign修饰的对象在释放之后,指针的地址还是存在的,也就是说指针并没有被置为nil。如果在后续的内存分配中,刚好分到了这块地址,程序就会崩溃掉。
而weak修饰的对象在释放之后,指针地址会被置为nil。
__weak和__block的区别
** __weak 本身是可以避免循环引用的问题的,使用__weak修饰的变量不会在block代码块中被retain,但是其会导致外部对象释放了之后,block 内部也访问不到这个对象的问题,我们可以通过在 block 内部声明一个 __strong 的变量来指向 weakObj,使外部对象既能在 block 内部保持住,又能避免循环引用的问题。**
__block 修饰的对象会被retain(MRC下不会retain)__block本身无法避免循环引用的问题,但是我们可以通过在 block 内部手动把 blockObj 赋值为 nil 的方式来避免循环引用的问题。另外一点就是 __block 修饰的变量在 block 内外都是唯一的,要注意这个特性可能带来的隐患。
MRC模式下
使用__block能够避免引起循环引用的问题
ARC模式下
使用__unsafe_unretained 和 __weak都可以避免循环引用的问题,但由于前者是unsafe的,会造成野指针问题,所以尽量少用unsafe_unretained关键字 另外在多线程环境下(block中的wSelf有可能被释放),需要先将self转为strong指针,避免在运行到某个关键步骤时self对象被释放。
总结:
- block 不是 property 时,用 self 即可,不需要用weakSelf
- block 是 property,需使用 weakSelf
- block 内多次使用 weakSelf,且有用到多执行,需使用 strongSelf
- 不是所有 block 都得用 weakSelf (事实上多数的 iOS 原生套件,以及 GCD 的 block 是不會造成 retain cycle 的,因为他们并沒有去 retain block)
网友评论