Search code examples
iosobjective-cblockobjective-c-blocksgrand-central-dispatch

Objective-C Block: return __block variable from block inside


OK, here is the code.

NSObject* (^executableBlock)(void) = ^NSObject*() {
    __block NSObject *refObj = nil;

    [Utility performAction:^() {
         if (conditionA)
              refObj = fooA;
         else
              refObj = fooB;
    };

    return refObj;
};

NSObject *result = executableBlock();   // result is nil

After executing the executableBlock, the result is nil and performAction block didn't be executed immediately and returned my expected value.

I know performAction block is executed within another thread and using the shared nil pointer refObj. Refer to Working with Blocks.

Here is my through, if I use GCD to call the performAction block and wait for its finish, how to rewrite it? Thanks!


Solution

  • By using semaphore, you can wait until a block is done.
    But completion-block may be suitable in your case, i think.

    NSObject* (^executableBlock)(void) = ^NSObject*() {
        __block NSObject *refObj = nil;
    
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    
        [self performAction:^() {
            if (conditionA)
                refObj = fooA;
            else
                refObj = fooB;
    
            dispatch_semaphore_signal(semaphore);
        }];
    
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    
        return refObj;
    };