Reputation: 12820
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
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
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
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
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