我有一个类似的方法:
- (void)loadStoreWithCompletion:(CompletionBlock)loadCompletion
{
dispatch_queue_t loadQueue = dispatch_queue_create("loadQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(loadQueue, ^{
// ... Do background stuff ...
});
dispatch_async(loadQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
loadCompletion();
});
});
dispatch_release(loadQueue);
}
我是否需要复制loadCompletion
块,因为只有在此方法的调用者不再存在时才会调用它,或者它是否正常?
答案 0 :(得分:3)
在另一个块中引用块参数的行为将导致它被隐式复制到堆中,因此您不需要显式地这样做。
答案 1 :(得分:3)
你可以依靠dispatch_async()
对直接传递给它的块做正确的事。还有一种情况是,当复制块时,它会复制由它捕获的任何块。由于loadCompletion
由内部块引用,并且未使用__block
声明,因此会捕获它。换句话说,你很好。
答案 2 :(得分:0)
这样很好。但是您应该对代码进行一次更改:
dispatch_async(loadQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
if (loadCompletion) {
loadCompletion();
}
});
});
您可以自己测试一下。如果您在没有任何参数([instance loadStoreWithCompletion:nil];
)的情况下调用该方法,则在您的代码版本中,应用程序将在调用完成处理程序时崩溃。块检查将防止在块不存在的情况下发生任何崩溃。
答案 3 :(得分:0)
调用者在堆栈上分配块,这意味着一旦超出范围,调用就会导致错误。
当您打算稍后使用它们时(例如在异步发生的回调中),您应该始终将它们复制到堆中,您可以这样做
[block copy]
copy
请注意保留它们或释放它们并不总是有效,因为它们可能处于堆叠状态。