假设我有以下typedef:
typedef void (^myBlock)(id);
我有一些方法 myMethod 接受 myBlock 作为参数并向其提供一些 id 变量:
void myMethod(id myObj, myBlock block) {
// ...
block(myObj);
// ...
}
所以,如果我有以下内容:
- (void) someMethod {
__block id myObj; // Some initialization local to the scope of someMethod;
// myObj = ... some assignment to myObj so it is not nil...
dispatch_async(someQueue(), ^{
// (*) Some long, possibly multi-queued and multi-blocked, processing,
// so we are sure that someMethod will run out:
// ...
// 1. Can I be sure that myObj is still alive and actual here
// after the long processing (*)?
myMethod(myObj, ^(id myObj) {
// (**) Some long, possibly multi-queued, processing here too...
// 2. Can I be sure that myObj is still alive and actual here
// after the long processing (**) finishes?
})
})
}
我是否必须特别保留myObj ,以便它能够在不同的队列/块中生存?
很抱歉,如果我问的是一些明显且足够的文档 - 我刚刚开始学习Objective-C,当时ARC可能是默认值,所以它不需要我太在意这些保留计数,自动释放和其他的东西,只在我这里描述的情况下考虑它们。
答案 0 :(得分:1)
- 在长时间处理(*)之后,我可以确定myObj还活着吗?
醇>
是的,即使你没有使用块说明符,因为块内的块保留了它。
- 在长时间处理(**)结束后,我能确定myObj还活着吗?
醇>
是的。块中使用的每个变量都由ARC保留。
PS:所有这一切都与ARC。
答案 1 :(得分:1)
- 在长时间处理(*)之后,我可以确定myObj还活着吗?
醇>
是。通常,块中的自由变量在复制时由块保留。但是,这是一个__block
变量。在ARC中,块也保留__block
个变量(但是,在MRC中并非如此)。
- 在长时间处理(**)结束后,我能确定myObj还活着吗?
醇>
此问题与捕获变量的块无关。这里,myObj
是未从周围范围捕获的参数,即局部变量。所以问题的确是,当调用块时,参数是否指向有效对象?由于myMethod()
只是同步调用其block
参数和它获得的myObj
参数,因此在ARC下,假设参数在调用myMethod
时有效,则不应该出错。即在外部区域)。这是事实,因为我们同意myObj
在上面的(1)中有效。