Does a passing of an object to a block guarantee that its lifecycle will be retained?

陌路散爱 提交于 2019-12-12 04:59:13

问题


Let's assume I have the following typedef:

typedef void (^myBlock)(id);

And I have some method myMethod accepting myBlock as an argument and yielding some id variable to it:

void myMethod(id myObj, myBlock block) {
    // ...
    block(myObj);
    // ...
}

So if I have the following:

- (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?
        })
    })
}

do I have to specially retain myObj so it would live across different queues/blocks?

Sorry if I'm asking something obvious and enough documented - I've just started learning Objective-C in the time, when ARC is likely a default so it does not require me to care much about these retain counts, autoreleases and other stuff, and think about them only in the situations like I described here.


回答1:


  1. Can I be sure that myObj is still alive and actual here after the long processing (*)?

Yes, and even if you weren't using the block specifier because the block inside the block retains it.

  1. Can I be sure that myObj is still alive and actual here after the long processing (**) finishes?

Yes.Every variable used inside a block is retained by ARC.

PS: All this with ARC.




回答2:


  1. Can I be sure that myObj is still alive and actual here after the long processing (*)?

Yes. Normally, free variables in a block are retained by the block when it is copied. However, this is a __block variable. In ARC, __block variables are also retained by the block (however, that is not the case in MRC).

  1. Can I be sure that myObj is still alive and actual here after the long processing (**) finishes?

This question isn't related to blocks capturing variables at all. Here, myObj is a parameter, i.e. a local variable, not captured from the surrounding scope. So the question really is, does the argument point to a valid object when the block is called? Since myMethod() simply synchronously calls its block argument with the myObj argument that it gets, under ARC, nothing should go wrong assuming that the arguments were valid when myMethod was called (i.e. in the outer block). This is true since we agreed that myObj was valid there from (1) above.



来源:https://stackoverflow.com/questions/13901447/does-a-passing-of-an-object-to-a-block-guarantee-that-its-lifecycle-will-be-reta

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!