将对象传递给块是否保证其生命周期将被保留?

时间:2012-12-16 12:51:55

标签: objective-c automatic-ref-counting objective-c-blocks retain

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

2 个答案:

答案 0 :(得分:1)

  
      
  1. 在长时间处理(*)之后,我可以确定myObj还活着吗?
  2.   

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

  
      
  1. 在长时间处理(**)结束后,我能确定myObj还活着吗?
  2.   

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

PS:所有这一切都与ARC。

答案 1 :(得分:1)

  
      
  1. 在长时间处理(*)之后,我可以确定myObj还活着吗?
  2.   

是。通常,块中的自由变量在复制时由块保留。但是,这是一个__block变量。在ARC中,块也保留__block个变量(但是,在MRC中并非如此)。

  
      
  1. 在长时间处理(**)结束后,我能确定myObj还活着吗?
  2.   

此问题与捕获变量的块无关。这里,myObj是未从周围范围捕获的参数,即局部变量。所以问题的确是,当调用块时,参数是否指向有效对象?由于myMethod()只是同步调用其block参数和它获得的myObj参数,因此在ARC下,假设参数在调用myMethod时有效,则不应该出错。即在外部区域)。这是事实,因为我们同意myObj在上面的(1)中有效。