Objective c 当一个块在执行过程中被设置为nil时会发生什么?

Objective c 当一个块在执行过程中被设置为nil时会发生什么?,objective-c,automatic-ref-counting,objective-c-blocks,Objective C,Automatic Ref Counting,Objective C Blocks,假设我有一个对块有强引用的对象。在执行该块期间的某个时候,强引用被设置为nil。是否保证块完成其执行,或者这会导致崩溃?我见过exc坏访问错误,但我不能可靠地生成它们,所以我不知道它们出现的确切原因 例如: -(void)method { self.block = ^{ //code self.block = nil; //more code - crash here? } } -(void)otherMethod { b

假设我有一个对块有强引用的对象。在执行该块期间的某个时候,强引用被设置为nil。是否保证块完成其执行,或者这会导致崩溃?我见过exc坏访问错误,但我不能可靠地生成它们,所以我不知道它们出现的确切原因

例如:

-(void)method
{
    self.block = ^{
        //code
        self.block = nil;
        //more code - crash here?
    }
}

-(void)otherMethod
{
    block();
}

当执行块的方法没有首先检查是否还有对块的引用时,可能会发生崩溃。如果缺少这样的检查,您可能会在方法中遇到这些崩溃

- (void)methodWithBlock:(void (^)(void))block
{
   if (block) // this check is to prevent crashes when calling to a released block pointer ...
   {
      block();
   }
}

您可能会遇到这样的代码,其中缺少这样的检查,这可能会导致您所经历的崩溃。我当然也经历过同样的情况。

文档似乎不能保证块在执行时会被保留。相反,GCD调用的文档,如
dispatch\u async
确实提供了这样的保证。从这一点来看,您似乎不能假设对块的普通调用将保留它

因此,在您的代码中,您可能需要:

-(void)otherMethod
{
    dispatch_block_t localBlock = Block_copy(block);
    localBlock();
    Block_release(localBlock);
}

我相信我终于对这个问题有了一个满意的答案。请注意,这都是在ARC的上下文中进行的

块在执行过程中可能会被解除分配。该块将继续正常执行,但其指向捕获的变量的任何指针都会变得可疑(并且有潜在的危险)

假设ObjectA有一个名为completion的块副本属性:

@property (nonatomic, copy) void (^completion)();
…其中任务看起来像这样:

__weak ObjectA * weakSelf = self;
self.completion = ^{
    weakSelf.completion = nil;
    [weakSelf doSomethingElse];
};
如果像这样调用块

-(void)method
{
    _completion(); //directly uses ObjectA's instance of the block
}
…然后,假设没有其他对象引用该块实例,则它将被解除分配,其捕获的变量weakSelf将变为nil。doSomethingElse永远不会被调用。解决这个问题的最佳方法是使用块的访问器调用块,这将在堆栈上分配一个新副本。原始副本将被释放,但新副本及其捕获的所有变量将在当前上下文中保留

-(void)method
{
    self.completion(); //uses new copy of the block
}

嗯,我不是这个意思。在我的场景中,当对该块的引用设置为NIL时,该块已经处于执行的中间。在您的场景中,问题是当您尝试开始执行nil块时。我认为您在这里没有必要担心。块是Objective-C对象。块不仅应保留对其使用的对象的引用,还应通过ARC管理块本身。如果正在调用它,则存在对其自身的引用。那么在ARC中呢?调用块是否可能在本地范围内创建强引用?