首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当一个块在执行过程中被设置为nil时会发生什么?

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

Stack Overflow用户
提问于 2012-09-05 07:49:54
回答 3查看 2.7K关注 0票数 5

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

例如:

代码语言:javascript
复制
-(void)method
{
    self.block = ^{
        //code
        self.block = nil;
        //more code - crash here?
    }
}

-(void)otherMethod
{
    block();
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-25 22:54:23

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

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

假设ObjectA有一个名为completion的块复制特性:

代码语言:javascript
复制
@property (nonatomic, copy) void (^completion)();

...where赋值如下所示:

代码语言:javascript
复制
__weak ObjectA * weakSelf = self;
self.completion = ^{
    weakSelf.completion = nil;
    [weakSelf doSomethingElse];
};

如果代码块是这样命名的.

代码语言:javascript
复制
-(void)method
{
    _completion(); //directly uses ObjectA's instance of the block
}

...then,假设其他任何东西都没有引用这个块的实例,它将被释放,其捕获的变量weakSelf将变为空。永远不会调用doSomethingElse。解决这个问题的最好方法是简单地使用它的访问器来调用块-这将在堆栈上分配一个新的副本。原始变量将被释放,但新的副本及其捕获的所有变量将在当前上下文中幸存下来。

代码语言:javascript
复制
-(void)method
{
    self.completion(); //uses new copy of the block
}
票数 3
EN

Stack Overflow用户

发布于 2012-09-05 08:42:25

这些文档似乎不能保证代码块在执行时会被保留。相反,dispatch_async等GCD调用的文档确实做出了这样的保证。从这一点上看,您似乎不能假设对块的普通调用会保留它。

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

代码语言:javascript
复制
-(void)otherMethod
{
    dispatch_block_t localBlock = Block_copy(block);
    localBlock();
    Block_release(localBlock);
}
票数 3
EN

Stack Overflow用户

发布于 2012-09-05 07:57:54

当执行块的方法没有首先检查是否仍然存在对块的引用时,可能会发生崩溃。你可能已经在方法中遇到过这些崩溃,就像这样的检查是缺失的。

代码语言:javascript
复制
- (void)methodWithBlock:(void (^)(void))block
{
   if (block) // this check is to prevent crashes when calling to a released block pointer ...
   {
      block();
   }
}

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12272783

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档