可以__weak在块的中间自我转nil?

时间:2015-03-30 10:04:27

标签: ios objective-c objective-c-blocks grand-central-dispatch

在我的后台线程中运行的块中使用__weak self引用时,我只需要在开头检查nil,还是__weak self即使在第一次nil测试通过后的执行期间也变为零?我想从块中的self访问一些ivars,并且在块执行时我需要最新的值。

3 个答案:

答案 0 :(得分:6)

如果没有人持有对self的引用,那么是。您可以通过在块

中使用强引用来缓解此问题
__weak __typeof(self) weakSelf = self;

^{
  __strong __typeof(weakSelf) strongSelf = weakSelf;
  if (!strongSelf) {
    return;
  }
};

答案 1 :(得分:1)

您可以通过从块内部强烈引用它来避免将引用设置为nil。

强烈引用块内的弱指针。

__weak MyObject *weakSelf = self; // a weak reference
myBlock = ^{
  MyObject *innerSelf = weakSelf; // a block-local strong reference
  NSLog(@"MyObject: %@", innerSelf); 
};

避免直接使用变量,因为它会导致保留周期。 如果直接在块中使用实例变量,则块将捕获self,因此您必须使用其访问器引用实例变量。

__weak MyObject *weakSelf = self;
myBlock = ^{
    MyObject *innerSelf = weakSelf; // a block-local strong reference
    NSLog(@"MyObject: %@", innerSelf);
    NSLog(@"MyObject ID: %d", innerSelf.objectID);
};

如果你直接使用实例变量:

NSLog(@"MyObject ID: %d", _objectID);

编译器将_objectID解释为self->_objectID,其中self被块捕获。

答案 2 :(得分:0)

在弱引用的性质中,当在另一个线程中删除最后一个强引用时,它可以随时变为零。如果你访问成员变量是因为你会崩溃,这是致命的,如果你在那个弱变量上调用一个方法,这是致命的,因为self是不安全的。

有一种简单的方法可以解决每个人使用的问题:在做任何事情之前将弱变量存储到字符串中,而不进行任何检查。然后检查强变量是否为零;该检查需要一次

在Xcode中打开所有警告,如果您做任何危险的事情,您将收到警告。