这篇文章主要讲以下几点
- block的循环引用是怎么产生的
- block的循环引用怎么解除
- block的引用究竟什么时候用weak什么时候用strong
先说一下demo结构,创建了一个person类,添加了name属性和一个参数返回值都为空的block属性,并重写了dealloc方法,里面打印person dealloc
放一段代码
Paste_Image.png看一下log
Paste_Image.png这就是一段典型的造成循环引用的代码,运行之后会发现person的dealloc方法并没有输出,虽然说到31行之后,p作为一个局部变量会被释放掉,但person创建的对象并没有释放掉
Paste_Image.png当程序运行起来的时候,内存分布大致就是上图中的分布形式,当程序运行到34行结束时,临时变量p会释放掉,也就是p指向person的强引用会去掉,但因为block内部使用了外部声明的强引用访问了person对象,所以block内部会自动产生一个强引用指向person对象,所以最后person和block的循环引用,都释放不了.
那么正确的姿势是什么呢.....
Paste_Image.png看一下log
Paste_Image.png这时候person就会被释放掉,那这又是为什么呢
Paste_Image.png再分析一下这个内存图,由于使用了__weak person *weakp = p,造成的结果就是block内部使用了弱引用weakP访问了person对象,那么block内部会自动产生一个弱引用指向person对象,在整个代码执行完的时候p作为局部变量释放掉,就发现没有一个强引用指向person对象,person对象就会立即释放,block也会跟着释放掉,从而打破了循环引用
写上两句MJ大神的总结>_<
如果[block内部]使用[block外部声明的强引用]访问[对象A] ,那么[block内部]会自动产生一个强引用指向[对象A];
如果[block内部]使用[block外部声明的弱引用]访问[对象A] ,那么[block内部]会自动产生一个弱引用指向[对象A];
牢记这两句话,再复杂的有关block的循环引用都能迎刃而解.
TODO:主要总结一下block更复杂的循环引用......
网友评论