0

假设我有以下 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 可能是默认设置,所以它不需要我太关心这些保留计数、自动释放和其他东西,并且只在我在这里描述的情况下考虑它们。

4

2 回答 2

1
  1. 经过长时间的处理(*)后,我可以确定 myObj 在这里仍然存在并且实际存在吗?

是的,即使您没有使用块说明符,因为块内的块保留了它。

  1. 在长时间处理 (**) 完成后,我可以确定 myObj 仍然存在并且实际存在吗?

是的。块内使用的每个变量都由 ARC 保留。

PS:这一切都与 ARC。

于 2012-12-16T12:58:53.317 回答
1
  1. 经过长时间的处理(*)后,我可以确定 myObj 在这里仍然存在并且实际存在吗?

是的。通常,块中的自由变量在复制时由块保留。然而,这是一个__block变量。在 ARC 中,__block变量也由块保留(但是,在 MRC 中不是这种情况)。

  1. 在长时间处理 (**) 完成后,我可以确定 myObj 仍然存在并且实际存在吗?

这个问题根本与块捕获变量无关。这里,myObj是一个参数,即一个局部变量,不是从周围的范围中捕获的。所以问题真的是,当块被调用时,参数是否指向一个有效的对象?由于简单地用它获得的参数myMethod()同步调用它的参数,在 ARC 下,假设参数在被调用时是有效的(即在外部块中)应该不会出错。这是真的,因为我们同意从上面的(1)那里是有效的。blockmyObjmyMethodmyObj

于 2012-12-16T21:54:09.917 回答