为什么 Block 中要用 __strong 再一次生命 weak 对象?

这时一次面试被问到和 Block 相关的问题, 当场就感叹"好问题啊"(对之前都没仔细思考过), 现在重新思考整理一下.

__weak __typeof(self)weakSelf = self;
Block(param)
^{
      __strong __typeof(weakSelf)strongSelf = weakSelf; 
      // Do stuff
});
  1. 先讨论没有 weakSelf 的情况, Block 会对 self 做一个强引用, 同时 Block 自身被 self 强引用, 导致出现经典的循环引用问题(S -> B -> S).
  2. weakSelf 就是为了打破循环出现的, 被 __weak 修饰符修饰的对象, 会随它的 strong 对象置空而自动置空, 同时不会引起引用计数的变化(S -> B -> WS). 其实到这里使用 weakSelf 就已经足够, 为什么还要在 Block 函数体里继续转换出 strongSelf 呢?
  3. 假若 Block 函数体在执行期间, self 被 dealloc, 此时函数体中可能出现前半部分 weakSelf 有效, 后半部分则变成 weakSlef==nil 的情况, 可能会导致 crash. 此时在 Block 中引入 用 __strong 修饰的 strongSelf, 相当于函数体中 self 不会因为外部操作而被强制置空. 当函数体执行完毕, strongSelf 因为作用域的结束而置空, 解除引用关系.

总结:

  1. 使用 weakSelf 解除循环引用
  2. 使用 strongSelf 提高安全性.

参考内容:

你可能感兴趣的:(ios,objective-c)