user1458963
user1458963

Reputation: 181

Return bool when Grand Central Dispatch job queue finished

I'd like to get a bool value after dispatch_group_notify finished. Unfortunately, the following code is wrong, and I have no idea on how to do it... Compilator tell me "Incompatible block pointer types passing 'BOOL'(^)(void)' to parameter of type 'dispatch_block_t'(aka 'void(^)(void^))" Any idea?

-(BOOL)saveToDB:(NSArray*)data{

// execute async the saveJSONDictionary
__block BOOL toReturn;
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("saveJsonDictionary", 0);
dispatch_group_async(group, queue, ^{
    for (int i = 0; i < [data count]; ++i) {
        NSDictionary* item = (NSDictionary*)[data objectAtIndex:i];
        [self saveJsonDictionary:item];
    }
    NSManagedObjectContext *moc = [[DatabaseManager sharedManager]managedObjectContext];
    toReturn = [moc save:nil];
});

dispatch_group_notify(group, queue, ^BOOL{
    return toReturn;
});

}

Upvotes: 1

Views: 1502

Answers (2)

Ramy Al Zuhouri
Ramy Al Zuhouri

Reputation: 22006

The parameter is a block that return void and doesn't accept any parameter, you can't force it to be another type of argument. You have to manually implement a mechanism to get the return value. For example:

dispatch_group_notify(group, queue, ^
{
    [self performSelectorOnMainThread: @selector(notifyValue:) withObject: @(trueOrFalse) waitUntilDone: NO];
});

The method:

- (void) notifyValue: (NSNumber*) value
{
    // You got the "virtual" return value of that method, you can use it.
}

Upvotes: 0

bbum
bbum

Reputation: 162722

First, there is no reason to create a new queue to only dispatch a single block. Toss that block onto one of the existing global queues and be done with it.

Secondly, you'll want to do something like this at the end of that block:

 ....
 BOOL success = [moc save:nil];
 dispatch_async(dispatch_get_main_queue(), ^{
     if (success)
         [someObjectThatCares theSaveIsAllDoneThanksAndComeAgain];
     else
         [someObjectThatCares saveFailedGetOutAndDoNotComeBackUntilYouGetItRight];
 });

That is, no need to use any complex mechanisms. Just add a bit of code at the end of your block that calls some method that can respond to the fact that saving is done.

Upvotes: 5

Related Questions