• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - 在异步 REST 请求的 block 内调用 self

[复制链接]
菜鸟教程小白 发表于 2022-12-12 09:35:47 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

[self userLoggedIn]withBlock block 内时,我无法调用它。它被调用但不显示 TITHomeViewController。如果我将它移到 block 的下方和外部,那么它可以正常工作。显然,我希望从 withBlock 中调用它,因为它是异步 REST 请求的完成处理程序。

- (void)doAuth
{
    // Call the Facebook API /me method
    [FBRequestConnection startForMeWithCompletionHandler:
     ^(FBRequestConnection *connection, id result, NSError *error)
     {
         // Populate global Facebook user info
         self.fbAccessToken = [[[FBSession activeSession] accessTokenData] accessToken];
         self.fbUserID = [result objectForKey"id"];

         // Authenticate with the Titter API
         [self callAPI"auth" withBlock:^(NSDictionary *jsonData) {
             NSString *_id = [jsonData objectForKey"_id"];
             if (_id != nil) {
                 self.userID = _id;
                 [self userLoggedIn];
             }
         }];
     }];
}

- (void)userLoggedIn
{
    // Display the home view.
    self.window.rootViewController = [[TITHomeViewController alloc] initWithNibName"TITHomeViewController" bundle:nil];
}

- (void)callAPINSString *)path withBlockvoid (^)(NSDictionary *jsonData))block
{
    // Initialize the API callback URL using global root and given path
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat"%@%@", apiRoot, path]];

    // The Titter API requires an authorization header formatted as [userID]@[accessToken]
    NSString *authorizationHeader = [NSString stringWithFormat"%@@%@", self.fbUserID, self.fbAccessToken];

    // Create the request and add our authorization header
    NSMutableURLRequest *restRequest = [[NSMutableURLRequest alloc] initWithURL:url];
    [restRequest addValue:authorizationHeader forHTTPHeaderField"authorization"];

    // Queue required for calling sendAsynchronousRequest
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    // Make an asynchronous request to our API and if there is no errors, return formatted JSON data to the passed block.
    [NSURLConnection
     sendAsynchronousRequest:restRequest
     queue: queue
     completionHandler:^(NSURLResponse *response,
                         NSData *data,
                         NSError *error) {
         if ([data length] >0 && error == nil) {
             NSLog(@"Succeeded! Data as string: %@", [NSString stringWithUTF8String:[data bytes]]);

             // Convert received JSON data into a NSDictonary object.
             NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];

             // Call back the block passed in.
             block(result);
         }
         else if ([data length] == 0 && error == nil) {
             NSLog(@"Nothing was downloaded.");
         }
         else if (error != nil) {
             NSLog(@"Error = %@", error);
         }
     }];
}



Best Answer-推荐答案


上面的评论线程让您完成了大约 90% 的任务! UI 在主线程上运行,对其的任何更新都应在 UI 线程上进行。您可以通过在主线程上调用 usedLoggedIn 在 block 代码中修复此问题:

dispatch_async(dispatch_get_main_queue(), ^{
  [self userLoggedIn];
});

还值得注意的是,您可能在 block 内使用 self 时遇到问题:如果 self 消失,该 block 将失败。在此用例中,这可能不是问题。您没有提及此代码来自哪个类:如果它来自 View Controller ,则可以安全地假设它不会去任何地方。但是,如果它是一个辅助对象或类似的东西,它可能会在请求 URL 时从您下方消失(或在该逻辑中的某个位置)。通常的做法是创建对 self 的弱引用以在 block 内使用,如下所示:

// Outside the block
MyViewController __weak *weakSelf = self;

// Inside the block
[weakSelf userLoggedIn];

关于ios - 在异步 REST 请求的 block 内调用 self,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23372265/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap