让iOS块同步执行

如何使块同步执行,或使函数在返回语句之前等待处理程序,以便数据可以从块传回?

-(id)performRequest:(id)args { __block NSData *data = nil; [xyzclass requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) { data = [NSData dataWithData:responseData]; }]; return data; } 

在这种情况下你可以使用信号量。

 -(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; } 

信号量将阻止执行进一步的语句,直到收到信号,这将确保您的函数不会过早返回。

asynchronous几乎总是更好。 但如果你想同步:

 -(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; } 

免责声明:CocoaCouchDeveloper说,当然这只会在完成块和runloop在同一个线程上时才起作用。 我认为,因为我知道许多(大多数)COMPLETION处理程序是这样工作的,但原则上它是有效的。

以上是不是线程安全的
使用信号灯或者什么的。
我也说过我不提倡这个

你可以添加一个方法来处理返回的数据,并在你的块中调用:

 -(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 }]; } 

您可以在另一个线程中执行同步请求,如下面的代码

 -(void)performRequest:(id)args { NSURLResponse *response = nil; NSError *error = nil; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; } 

从主线程你可以调用这个

 [self performSelectorInBackground:@selector(performRequest:) withObject:args]; 

否则你可以使用下面的方法做asynchronous请求

 [NSURLConnection alloc]initWithRequest:request delegate:self]; 

并为NSURLConnection实现委托方法

你确定你想同步吗? 如果是的话,你可以调用(或放)你的处理函数在你的块或使用Jignesh的build议(并使用“performSelectorInMainThread”当你的处理程序完成,你想返回值。

asynchronous的方式是(一点点)更难,但更好,因为: – 它迫使你写干净的代码(不传递方便的variables) – 你可以执行其他的事情,使用户不会等待,并认为你的应用程序是慢的。

你应该真的给它​​两三个小时去asynchronous。 小痛苦充分获得。 你也可以看看键值观测。

你可以这样做。

 -(id)performRequest:(id)args { __block NSData *data = nil; [xyzclass performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { dispatch_sync( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{ data = [NSData dataWithData:responseData]; }); }]; return data; }