我们什么时候应该将weakSelf改为strongSelf?

时间:2017-07-13 02:55:55

标签: objective-c block

我知道当我们使用block时,我们应该使用weakSelf来避免保留循环。但是我看到有时候会有一个强大的自我。

困惑我的是:

  1. 为什么必须将弱自己改为强自我?
  2. 如果我们不将弱者变为强者自己会发生什么可怕的事情?
  3. 什么时候应该将weakSelf改为strongSelf?
  4. 希望有人能给出一个确切的例子。

    提前致谢。

3 个答案:

答案 0 :(得分:3)

  1. 为什么必须将弱者变为强者自我?
  2. 如果对self的引用已经为nil(用户取消了视图),有时您希望块不执行。这就是您首次使用弱引用的原因。 (共同案例)

    但是,有时你希望你的块完成执行,确保它所引用的所有内容都存活,但只有当“自身”仍然存在时一旦块开始。在这种情况下,您使块将弱引用转换为强引用。 (稀有案例)

    1. 如果我们不改变弱自己到强自我会发生什么可怕的事情?
    2. 如果块在self处于活动状态时开始执行(允许它开始)但在处理过程中被解除分配(考虑一个耗时的功能,如图像处理),然后块从self访问资源(它不再存在)它会崩溃。

      1. 我们何时应该将weakSelf改为strongSelf?
      2. 几乎没有。我能想到的唯一例子是,当你的块开始执行时,它绝对需要来自“self”的资源。

        这个答案有更详细的解释:

        Strong reference in the block, it will be retained?

答案 1 :(得分:3)

在块中捕获self作为弱引用或强引用的唯一原因是块以某种方式使用它

self被捕获时,它的使用方式将决定何时以及是否需要先制作一份强大的副本。

如果块将多次使用捕获的引用,则应始终使用强复制,这可确保引用在块内的所有用途中保持活动状态,并避免多次加载弱引用的成本。 / p>

例如,在块的功能取决于self是否仍然存在,那么通常会先制作一个强引用并对其进行测试。有点像:

__weak __typeof(self)weakSelf = self;
myBlock = ^{
              // make local strong reference to self
              __typeof(weakSelf) strongSelf = weakSelf; 
              // check if self still exists and process accordingly
              if (strongSelf)
              {
                 // do whatever is needed if "self" still exists
                 // strongSelf will keep the object alive for the
                 // duration of the call
              }
              else
              {
                 // do whatever, if anything, is needed if "self" no longer exists
              }
           });

但是,如果块的操作只需要使用self引用的对象,则可能永远不会生成强拷贝。

HTH

答案 2 :(得分:0)

在任何情况下,您都需要在回调返回后使用“自我”-将弱自我变成强自我永远都是错误的,在最坏的情况下-只需附加代码即可。但事实并非如此。 这是一个非常简单的示例,您确实需要一个强大的参考。

 __weak typeof(self) weakSelf = self;
    [self.bgQueue1 addOperationWithBlock:^{
        [weakSelf doSomeMagic:weakSelf.importentArr arg:number];
        if (weakSelf.importentArr.count == 10){
            //we will have crash(or other unpredictable results) if weakSelf will turns to nil
            [DataBaseClass save:weakSelf.importentArr];
        }
    }];