0

我正在尝试理解 Objective-C 中的块。以登录 Twitter 为例。我希望主线程等到块完成。

我怎样才能在下面的代码中实现这一点。showMain 方法只是过渡到下一个视图。数组 TweetArray 为空,因为异步块未完成。现在,我正在使用方法 performSelectorOnMainThread:withObject:waitUntilDone:。请详细解释块的概念。

    [account requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error)
     {
         [MBProgressHUD showHUDAddedTo:self.view animated:YES];
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
             if (granted)
             {
                 NSArray *accounts = [account accountsWithAccountType:accountType];
                 // Check if the users has setup at least one Twitter account
                 if (accounts.count > 0)
                 {
                     ACAccount *twitterAccount = [accounts objectAtIndex:0];

                     SLRequest *twitterInfoRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:@"https://api.twitter.com/1.1/users/show.json"] parameters:[NSDictionary dictionaryWithObject:twitterAccount.username forKey:@"screen_name"]];
                     [twitterInfoRequest setAccount:twitterAccount];

                     // Making the request
                     [twitterInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
                         dispatch_async(dispatch_get_main_queue(), ^{
                             if ([urlResponse statusCode] == 429) {
                                 return;
                             }
                             if (error) {
                                 return;
                             }
                             // Check if there is some response data
                             if (responseData) {
                                 NSError *error = nil;
                                 NSArray *TweetArray = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];

                                 NSLog(@"%@", TweetArray);
                             }
                         });
                     }];
                 }
             } else {
                 NSLog(@"Access denied");
             }
         });

         dispatch_async(dispatch_get_main_queue(), ^{
             [MBProgressHUD hideHUDForView:self.view animated:YES];

             [self performSelectorOnMainThread:@selector(showMain) withObject:nil waitUntilDone:YES];
         });
     }];

谢谢,迈克

4

1 回答 1

1

解释块的整个概念只是一个答案是要求太多,你应该阅读文档并在一些书籍中搜索。

但是直接看你的问题,我会试着告诉你发生了什么:

这个performRequestWithHandler:来自你的twitterInfoRequest对象的方法,就像名字已经说过的那样,对 twitter 的服务器执行请求,返回一个responseData. 该方法接收一个块作为参数,该块将在申请到达时准确调用。所以,这个块只不过是一段代码,当你收到它时,它handle会被执行。responseData

所以,如果你想在响应到达做一些事情,你必须把它放在这个块中。在您的情况下,这将是对showMain方法的调用:

(...)
[twitterInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
                     dispatch_async(dispatch_get_main_queue(), ^{
                         if ([urlResponse statusCode] == 429) {
                             return;
                         }
                         if (error) {
                             return;
                         }
                         // Check if there is some response data
                         if (responseData) {
                             NSError *error = nil;
                             NSArray *TweetArray = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];

                             NSLog(@"%@", TweetArray);

                             [self showMain];
                         }
                     });
                 }];

Ps:由于您已经在主线程内(使用 dispatch_async(dispatch_get_main_queue()...)执行此句柄块,因此您不必通过performSelectorOnMainThread.

于 2013-08-29T02:09:29.853 回答