0

当我想从Facebook获取用户ID时,我需要等待API“startWithCompletionHandler”发送给我userID,然后继续我的任务。就像下面列出的代码一样。阻止并等待异步操作Objective-C

但我不能使用dispatch_semaphore或dispatch_group等待api回调。除了completionHandler之外,像MagicalRecord中的“blockAndWait”这样的其他解决方案可以帮助我解决这样的问题吗?

此外,下面列出的解决方案不起作用。它似乎阻止了主线程,所以它会继续记录“WAITING”并且不能弹出Facebook登录视图。

-(void)getAccountIDAndWait{ 
__block BOOL isFinish = NO; 
[[FBRequest requestForMe] startWithCompletionHandler: 
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *aUser, NSError *error) { 
    if (error) { 
     NSLog(@"bug in getAccountIDAndWait"); 
     return; 
    } 

    self.accountID = [aUser objectForKey:@"id"]; 
    isFinish = YES; 
}]; 

while(isFinish==NO){ 
    sleep(0.1); 
    NSLog(@"WAITING"); 
} 

}

回答

0

您正在使用有的方法是阻塞。正如你正确观察,这不是你想要的。这里的设计意图是让您在完成处理程序中的请求完成后,将想要发生的事情放入其中。

1

扩展Chuck说我稍微修改了代码以允许getAccountIdAndWait函数完成(因此主线程空闲),并且在调用completionHandler时它将调用doTheNextThing函数。

-(void)getAccountIDAndWait{ 
    [[FBRequest requestForMe] startWithCompletionHandler: 
    ^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *aUser, NSError *error) { 
     if (error) { 
      NSLog(@"bug in getAccountIDAndWait"); 
      return; 
     } 

     self.accountID = [aUser objectForKey:@"id"]; 
     [self doTheNextThing]; 
    }]; 

} 
+0

如果你在一个块内访问self,这会导致一个保留周期吗? –

+0

但我想要的是等待completionHandler完成,然后doTheNextThing。任何方式我可以做到这一点? – allenlinli

+1

@ VenkatS.Rao访问块内的自我并不一定意味着你有一个保留周期。只有这种情况下,该块也由自己保留(直接或间接)。 – NSAdam