Question

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.

Was it helpful?

Solution

  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.

OTHER TIPS

  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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top