假设我有一个对象,它具有对一个块的强引用。在该块执行期间,强引用有时被设置为零。代码块是否可以保证完成其执行,或者这是否会导致崩溃?我见过exc-bad-access错误,但我不能可靠地生成它们,所以我不知道它们出现的确切原因。
例如:
-(void)method
{
self.block = ^{
//code
self.block = nil;
//more code - crash here?
}
}
-(void)otherMethod
{
block();
}发布于 2013-06-25 22:54:23
我相信我终于对这个问题有了令人满意的答案。请注意,这一切都是在ARC的上下文中进行的。
在执行过程中,块可能会被释放。该块将继续正常执行,但它的任何指向捕获变量的指针都会变得可疑(并且可能有危险)。
假设ObjectA有一个名为completion的块复制特性:
@property (nonatomic, copy) void (^completion)();...where赋值如下所示:
__weak ObjectA * weakSelf = self;
self.completion = ^{
weakSelf.completion = nil;
[weakSelf doSomethingElse];
};如果代码块是这样命名的.
-(void)method
{
_completion(); //directly uses ObjectA's instance of the block
}...then,假设其他任何东西都没有引用这个块的实例,它将被释放,其捕获的变量weakSelf将变为空。永远不会调用doSomethingElse。解决这个问题的最好方法是简单地使用它的访问器来调用块-这将在堆栈上分配一个新的副本。原始变量将被释放,但新的副本及其捕获的所有变量将在当前上下文中幸存下来。
-(void)method
{
self.completion(); //uses new copy of the block
}发布于 2012-09-05 08:42:25
这些文档似乎不能保证代码块在执行时会被保留。相反,dispatch_async等GCD调用的文档确实做出了这样的保证。从这一点上看,您似乎不能假设对块的普通调用会保留它。
因此,在您的代码中,您可能需要:
-(void)otherMethod
{
dispatch_block_t localBlock = Block_copy(block);
localBlock();
Block_release(localBlock);
}发布于 2012-09-05 07:57:54
当执行块的方法没有首先检查是否仍然存在对块的引用时,可能会发生崩溃。你可能已经在方法中遇到过这些崩溃,就像这样的检查是缺失的。
- (void)methodWithBlock:(void (^)(void))block
{
if (block) // this check is to prevent crashes when calling to a released block pointer ...
{
block();
}
}您可能会遇到这样的检查缺失的代码,这可能会导致您所经历的崩溃。我当然也有过同样的经历。
https://stackoverflow.com/questions/12272783
复制相似问题