I have a delegate class that needs to return data for certain methods. My problem is that some of the calls that I make to get that data are async (using completion blocks), so it's difficult to return from the method with the data in hand. Here is what I came up with:
- (NSArray *)contentsAtPath:(NSString *)path
{
__block NSMutableArray *contentsArray = [NSMutableArray array];
__block BOOL blockProcessing = YES;
SuccessBlock success = ^(MyResult *result)
{
for (NSUInteger i = 0; i < result.count; i++)
{
MyItem *item = [result objectAtIndex:i];
[contentsArray addObject:item];
}
blockProcessing = NO;
};
[self.dataManager itemsAtPath:path success:success failure:nil];
while (blockProcessing) {
// wait for block to complete
}
return contentsArray;
}
Is there any better way to achieve this without having the while loop?
Sure. Something like this might work:
- (NSArray *)contentsAtPath:(NSString *)path
{
NSMutableArray *contentsArray = [NSMutableArray array];
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
SuccessBlock success = ^(MyResult *result)
{
for (NSUInteger i = 0; i < result.count; i++)
{
MyItem *item = [result objectAtIndex:i];
[contentsArray addObject:item];
}
dispatch_semaphore_signal(sem);
};
[self.dataManager itemsAtPath:path success:success failure:nil];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
// If not ARC then
// [sem release];
return contentsArray;
}
Also note that regardless, contentsArray
does not need the __block
specifier (at least for the code here).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.