【问题标题】:NSURLConnection sendAsynchronousRequest:queue:completionHandler not working in iOS 4.3NSURLConnection sendAsynchronousRequest:queue:completionHandler 在 iOS 4.3 中不起作用
【发布时间】:2012-06-02 05:56:58
【问题描述】:

我在我的应用程序中使用[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)。通过使用这个,我的应用程序在 iOS 4.3 中终止,但在 iOS 5.0 中运行良好。

如何在 iOS 4.3 中使用它,任何人都可以帮助我。

【问题讨论】:

  • 第一步:使用合理的短标题并格式化您的代码。

标签: objective-c ios ios5 nsurlconnection ios4


【解决方案1】:

这是一个适合我的完整实现。随意重命名它并添加为NSURLConnection 上的类别,或者只是将其添加为您正在使用的类中的本地方法。

-(void)sendAsynchronousRequest:(NSURLRequest*)request queue:(NSOperationQueue*)queue completionHandler:(void(^)(NSURLResponse *response, NSData *data, NSError *error))handler
{
    __block NSURLResponse *response = nil;
    __block NSError *error = nil;
    __block NSData *data = nil;

    // Wrap up synchronous request within a block operation
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        data = [NSURLConnection sendSynchronousRequest:request 
                                     returningResponse:&response 
                                                 error:&error];
    }];

    // Set completion block
    // EDIT: Set completion block, perform on main thread for safety
    blockOperation.completionBlock = ^{

        // Perform completion on main queue
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            handler(response, data, error);
        }];
    };

    // (or execute completion block on background thread)
    // blockOperation.completionBlock = ^{ handler(response, data, error); };

    // Execute operation
    [queue addOperation:blockOperation];
}

编辑 我不得不修改方法,因为我在完成块中进行 UIKit 调用(例如更新标签等)。所以在主线程上调用完成块其实更安全一些。 (原版已注释掉)

【讨论】:

    【解决方案2】:

    您尝试使用的方法仅适用于 iOS 5。对于早期的操作系统,请考虑使用

    + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
    

    并将其包装到一个新线程中以实现异步行为。

    【讨论】:

    • 最好继续使用 NSURLConnection 的异步行为,安排在主线程的运行循环中,并带有适当的委托。
    • @KenThomases - 有什么具体原因更好吗? H2CO3 不正是描述了该便捷方法的用途吗?只是你会阻塞一个线程吗?
    • 是的。由于NSURLConnection 提供了异步模式,因此没有理由仅仅为了防止阻塞主线程而创建线程。
    【解决方案3】:

    H2CO3Ken Thomases 的建议都是正确的。

    另外,你可以看看ios4-implementation-of-nsurlconnection-sendasynchronousrequestqueuecompletio

    如果您使用主队列作为完成处理程序执行的队列,您可以使用(如 Tom 建议的)委托模式。为避免重复代码,您可以在 NSURLConnection 委托机制上使用包装器。

    在另一种情况下,如果您想保持异步行为并且不想处理同步调用(如 H2CO3 建议的那样,请注意他的建议也是有效的)和完成处理程序在不同的队列中执行,那么我建议您将异步委托模式包装在 NSOperation 类中。这种方法相当困难,但您可以在 Concurrent Operations Demystified 中找到一个很好的方法(参见这两篇文章)。

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 2012-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多