Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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!

share|improve this question

3 Answers 3

up vote 0 down vote accepted

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;
};
share|improve this answer
    
Thanks for your tips, I just found an answer after searching keywords dispatch_semaphore_create. Link: stackoverflow.com/a/4326754/1677041 –  Itachi Jan 19 at 6:03

I would considering the following re-structure:

    __block NSObject * result;
    void (^executableBlock)(NSObject *) =  ^void (NSObject * obj)
    {
        [self performAnActionWithBlock:^(BOOL success)
        {
            if (success) {
                result = obj;
                NSLog(@"results: %@", result);
            }else{
               result = nil;
            }

        }];
    };
    executableBlock(@"Hello");


//where:
-(void)performAnActionWithBlock:(void(^)(BOOL))block{
    block(YES);
}

You should then be able to call result from elsewhere

share|improve this answer
void (^executableBlock)(NSObject*) = ^(NSObject *arg) {

[Utility performAction:^(NSObject *arg) {
     if (conditionA)
          arg = fooA;
     else
          arg = fooB;
}];

};

__block NSObject *result = nil;

executableBlock(result); // result will be changed in block

share|improve this answer
    
Please add more detail about your answer and why this answer works. –  SAM Jan 19 at 5:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.