the_critic
the_critic

Reputation: 12820

How to return data from background thread ?

I have a method that should return an array which is populated in a background thread. I would like to wait with the return statement until the array is completely populated. How would I do that ? I know how to process data with no return type, but I would like to call this function and get the populated array.

Example (Here the array ends up empty because it returns before array is populated - I would like to do something to return the populated array) :

-(NSArray*)fetchSomeArray{

    __block NSArray *arrayToReturn;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,(unsigned long)NULL), ^(void) {

        NSArray *someArray = ...; // getting some array from database
        arrayToReturn = [NSMutableArray new];

        for(int i=0;i<someArray.count;i++){

            [arrayToReturn addObject:...];
        }

    });

    return arrayToReturn;

}

Upvotes: 0

Views: 6520

Answers (4)

Rui Peres
Rui Peres

Reputation: 25907

Use delegation, or blocks and take out the return arrayToReturn;. After your "for" and inside the "dispatch_async":

dispatch_async(dispatch_get_main_queue(),^{
      [myDelegate passComputedArray:arrayToReturn];
});

Upvotes: 7

lakshmen
lakshmen

Reputation: 29064

- (void)someMethod:(void (^)(BOOL result))completionHandler {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //all your functionality

        // Check that there was not a nil handler passed.
        if( completionHandler ){
            //your function to so that you can return
        }
        });
    });

Pass the completionHandler and once done, do your function

Upvotes: 4

Peter DeWeese
Peter DeWeese

Reputation: 18333

If you want to wait until it returns, it is unnecessary to background it.

-(NSArray*)fetchSomeArray{
    NSArray *someArray = ...; // getting some array from database
    return someArray;
}

But I'll bet that you really want to do something with that returned value which takes some time to compute without blocking the main thread, so you can instead pass the array back to a method in the same object or elsewhere.

-(void)fetchSomeArray{
    __block id bself = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,(unsigned long)NULL), ^(void) {
        NSArray *someArray = ...; // getting some array from database
        [bself arrayFetched:someArray];
    });

    return arrayToReturn;
}

-(void)arrayFetched:(NSArray*)array{
    // do something with the returned array
}

Upvotes: 1

Putz1103
Putz1103

Reputation: 6211

The easiest way to deal with this would be to call a function once the array is complete and process the array there.

-(void)fetchSomeArray{
    __block NSArray *arrayToReturn;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,(unsigned long)NULL), ^(void) {

    NSArray *someArray = ...; // getting some array from database
    arrayToReturn = [NSMutableArray new];

    for(int i=0;i<someArray.count;i++){

        [arrayToReturn addObject:...];
    }

    [self finishedArrayResult:arrayToReturn];

});

}

But if you wanted that return function to update anything n the UI you would need to run that function in the main thread and not the background. To do that you could either use performSelector: onThread: withObject: waitUntilDone: or you could use another dispatch_async using the main thread instead of global thread.

Upvotes: 0

Related Questions