【iOS】__block和__weak内存管理,防止内存泄露

环境:block函数内
先写结论:
在MRC下,咱们一般使用__block,而在ARC下咱们一般使用__weak, 或者__unsafe_unretaine __block(不安全,不建议使用) 来修饰对象防止循环引用而形成的内存泄露。

注意:
__weak 自己是能够避免循环引用的问题的,可是其会致使外部对象释放了以后,block 内部也访问不到这个对象的问题,咱们能够经过在 block 内部声明一个 __strong 的变量来指向 weakObj,使外部对象既能在 block 内部保持住,又能避免循环引用的问题
__block 自己没法避免循环引用的问题,可是咱们能够经过在 block 内部手动把 blockObj 赋值为 nil 的方式来避免循环引用的问题。另一点就是 __block 修饰的变量在 block 内外都是惟一的,要注意这个特性可能带来的隐患。


在MRC中,
__block经过用在修改局部变量数据,使变量数据生效,变量会在内存中强引用。
__block关键字能够知足block内修改block外变量的需求,__weak能够解决循环引用的问题

问题:__block也能够解决循环引用的问题?
为何会说block也能够起到和weak同样的做用呢?
之前在非arc环境中,__block修饰的变量在Block copy时是不会retain的,因此,也能够作到破解循环引用。
因此说是指在非ARC环境中__block能够解决循环引用问题


http://www.devdiv.com/ios_weak_block_-blog-70053-56933.html html


http://blog.sina.com.cn/s/blog_cf6377e70102vhq8.htmlios

官方解释:From the docs about __block安全

__block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created w函数

So they are technically different things. __block is to stop your variable being copied from your external scope into your block scope. __weak is a self delimiting weak pointer.spa

From the docs about __weakcode

__weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.orm

中文意思,请你们自行理解,咱们来看你们的解释,纵观国内技术文章,基本都是一说一大片,发现真正没有解决以前的疑问,有什么不一样,好了,先看下面的这段话:htm

So they are technically different things. __block is to stop your variable being copied from your external scope into your block scope. __weak is a self delimiting weak pointer.对象

Note I said technically, because for your case they will do (almost) the same thing. The only difference is if you are using ARC or not. If your project uses ARC and is only for iOS4.3 and above, use __weak. It ensures the reference is set to nil if the global scope reference is releases somehow. If your project doesn't use ARC or is for older OS versions, use __block.blog

There is a subtle difference here, make sure you understand it.

EDIT: Another piece to the puzzle is __unsafe_unretained. This modifier is almost the same as __weak but for pre 4.3 runtime environments. HOWEVER, it is not set to nil and can leave you with hanging pointers.

总结以下:

AIn manual reference counting mode, __block id x; has the effect of not retaining x. In ARC mode, __block id x; defaults to retaining x (just like all other values). To get the manual reference counting mode behavior under ARC, you could use __unsafe_unretained __block id x;. As the name __unsafe_unretained implies, however, having a non-retained variable is dangerous (because it can dangle) and is therefore discouraged. Two better options are to either use __weak (if you don’t need to support iOS 4 or OS X v10.6), or set the __block value to nil to break the retain cycle.

也就说,在MRC下,咱们一般使用__block ,而在ARC下咱们一般使用__weak , 或者__unsafe_unretaine __block(不安全,不建议使用) 来修饰对象防止循环引用而形成的内存泄露。