循环引用会导致崩溃吗?
1 2 3 4 5 | |
block 没有调用前, self delloc了,在 block 里面 strongself 应该可以获取的变量,个人理解,block 中的 self 算是局部变量,有 block 持有,销毁情况只跟 block 有关系
也有人说 strongSelf 只是保证在 block 里面有值,这样说也没错,我测试也是 strong 里面保持有值得,即使外部的 self 释放了,所以内部才用 strongSelf 啦
那平常我们在没有用这个框架的时候,都是用__weak,这样的话, block 里边的weakself,在self dealloc后 , 还有么?dealloc 会置为 nil
1 2 3 4 | |
是的,这样可以避免block执行过程中self对象被释放
外部的 weak 是为了防止因为 self 导致的循环引用,但是如果这时候 self 被释放的话,内部的 weakself 就为空了,所以一般内部会用 __strong 生声明一下 __weak typeof(self) weakSelf = self; 最安全用法:block外部: __weak __typeof(self) weakSelf = self; block内部: __strong __typeof(weakSelf) strongSelf = weakSelf; why: weakSelf 是为了block不持有self, 避免循环引用, 而再声明一个strongSelf是因为一旦进入block执行, 就不允许self在这个执行过程中释放. block执行完成后这个strongSelf会自动释放, 没有循环引用问题.
1 2 3 4 5 6 | |
block内部发送了两条消息, 如果只是一条, 那么采用weakSelf是没有问题的.但如果是两条消息,y通过看Clang的document能够看到, 以为Clang有可能会重新计算对象的引用计数, weakSelf有可能被置为nil, 这一过程发生在block内部执行完doThis之后, 还没有执行doThat之前.
我现在这外部 weakself 释放了,里面的 strongself 也跟着释放了.
那么这里用
weakself 是不是不对呢?
刚才那里用weakSelf是没错的。为什么?
1 2 3 4 5 6 7 8 9 | |
typeof()括号里面的是 weakSelf啦
这样block会把weakSelf放到内部的一个持有变量表里面,我测试,当在内部强引用这 self, 视图被销毁,先走 delloc, 然后 strongself 还是存在的。
不是有一个持有变量表么,按道理来讲block中的weakself,应该是一直有的啊block持有weakSelf,因为是weak变量所以不会增加引用计数。如果self对象在block执行之前就没有其他strong变量持有它,就会释放,后面block执行的时候weakSelf就已经是nil了。但是如果block开始执行,strongSelf又持有了self对象,这时候即使没有其他strong变量持有,self对象也不会释放。block执行完毕后,局部变量strongSelf被系统自动回收,这时候self变量引用计数会-1,如果没有其他变量持有,就会释放。总之,strongSelf不能确保block执行时self对象还存在,但是一旦开始执行时self还在,strongSelf可以给self续命到block执行结束
1 2 3 4 5 6 7 8 | |
这个就会崩溃。 嗯,循环引用大致是这样