菜鸟教程小白 发表于 2022-12-12 09:35:47

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


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

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

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

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

- (void)callAPI:(NSString *)path withBlock:(void (^)(NSDictionary *jsonData))block
{
    // Initialize the API callback URL using global root and given path
    NSURL *url = ];

    // The Titter API requires an authorization header formatted as @
    NSString *authorizationHeader = ;

    // Create the request and add our authorization header
    NSMutableURLRequest *restRequest = [ initWithURL:url];
    ;

    // Queue required for calling sendAsynchronousRequest
    NSOperationQueue *queue = [ 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 ( &gt;0 &amp;&amp; error == nil) {
             NSLog(@&#34;Succeeded! Data as string: %@&#34;, ]);

             // Convert received JSON data into a NSDictonary object.
             NSDictionary *result = ;

             // Call back the block passed in.
             block(result);
         }
         else if ( == 0 &amp;&amp; error == nil) {
             NSLog(@&#34;Nothing was downloaded.&#34;);
         }
         else if (error != nil) {
             NSLog(@&#34;Error = %@&#34;, error);
         }
   }];
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>上面的评论线程让您完成了大约 90% 的任务! UI 在主线程上运行,对其的任何更新都应在 UI 线程上进行。您可以通过在主线程上调用 <code>usedLoggedIn</code> 在 block 代码中修复此问题:</p>

<pre><code>dispatch_async(dispatch_get_main_queue(), ^{
;
});
</code></pre>

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

<pre><code>// Outside the block
MyViewController __weak *weakSelf = self;

// Inside the block
;
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 在异步 REST 请求的 block 内调用 self,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/23372265/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/23372265/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 在异步 REST 请求的 block 内调用 self