objc-zen-book-cn icon indicating copy to clipboard operation
objc-zen-book-cn copied to clipboard

关于weekSelf和strongSelf中的问题

Open RhettTamp opened this issue 7 years ago • 2 comments

你好,原文在讲__weak和__strong关键字的时候举了官方文档的一个例子

MyViewController *myController = [[MyViewController alloc] init...];
// ...
MyViewController * __weak weakMyController = myController;
myController.completionHandler =  ^(NSInteger result) {
    MyViewController *strongMyController = weakMyController;
    if (strongMyController) {
        // ...
        [strongMyController dismissViewControllerAnimated:YES completion:nil];
        // ...
    }
    else {
        // Probably nothing...
    }
};

然后作者说self不能被delloc和赋值为nil。我觉得这里是没有问题的,文档中使用MyViewController * __weak weakMyController = myController;,这里让一个新的指针指向weakMyController所指的指针,但是引用计数应该是没有增加的,这里可以理解成是一个局部变量?然后当block结束该指针会自动释放,所以self还是能够被正常的销毁。

我也不知道我理解的对不对,希望大神指教。

RhettTamp avatar Mar 30 '17 13:03 RhettTamp

hi, 我调整了一下 issue 中代码的排版。

这个问题原文也没有用很确定的语气,我也是来共同探讨下。

如果直接在 block 内使用 block 外定义的 weakController, 那么在多线程执行的时候,比如在 block 内

  if (weakController) {
     doA();
     doB();
  }

如果在 doA() 完成后,其他线程获取了控制权,减少了 weakController 的 retain,那么 weakController 可能就会变成 nil,继续执行代码块的 doB() 时候就出问题。

如果是以上述苹果文档里的方式执行:

    MyViewController *strongMyController = weakMyController;
   if (strongMyController) {
        doA();
        doB();
    }

strongMyController 是在代码块运行的时候生成强引用,并且保证在这个 block 运行的时候,对象不被释放。所以原文说道

在 block 内用强引用的优点是,抢占执行的时候的鲁棒性。
...
 和并发执行有关。当涉及异步的服务的时候,block 可以在之后被执行,并且不会发生关于 self 是否存在的问题。

这样就可以解释通了。

不过这个问题 苹果的文档 和其他讨论 也没说得很明白,要彻底弄清楚恐怕还是需要查阅更多资料和做实验研究下。我暂时没想到如何精确找到 strong reference of weak reference in blocks 相关资料的方法。欢迎进一步探讨。

oa414 avatar Mar 30 '17 15:03 oa414

嗯,我大概也是你这个意思,生成那个强引用主要就是防治self提前释放吧,但是它并不会造成引用循环,因为代码块结束后它还是要自动释放的

RhettTamp avatar Mar 31 '17 11:03 RhettTamp