How can I make a block execute synchronously, or make the function wait for the handler before the return statement, so the data can be passed back from the block?
-(id)performRequest:(id)args
{
__block NSData *data = nil;
[xyzclass requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
data = [NSData dataWithData:responseData];
}];
return data;
}
You can use semaphores in this case.
-(id)performRequest:(id)args
{
__block NSData *data = nil;
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
[xyzclass requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
data = [NSData dataWithData:responseData];
dispatch_semaphore_signal(sem);
}];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
return data;
}
semaphore will block execution of further statements until signal is received, this will make sure that your function does not return prematurely.
async is almost always better. but if you want synchronous:
-(id)performRequest:(id)args
{
__block NSData *data = nil;
[xyzclass requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
data = [NSData dataWithData:responseData];
}];
while(!data) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
return data;
}
Disclaimer: CocoaCouchDeveloper says that of course this will only work if the completion block and the runloop are on the same thread. I assumed that because many(most) COMPLETION handler I know work that way but of it is valid in principle.
The above is not thread safe
use a semaphore or something maybe.
also I said I don't promote this
You could just add a method which processes the returned data and call that in your block:
-(void)performRequest:(id)args{
__block NSData *data = nil;
[xyzclass requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
data = [NSData dataWithData:responseData];
[self processData:data]; //method does something with the data
}];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With