4

在我所见的任何地方,我都看到人们明确地使用队列或运行循环来进行网络操作。我应该在 iOS 5 中仍然这样做,还是应该NSURLConnection sendAsynchronousRequest:queue:completionHandler:改用?这是在 iOS >= 5 中进行网络操作的首选方法吗?

4

4 回答 4

4

我无法回答其他人的偏好,但我推出了自己的< os5,并且我非常喜欢块操作。a) 我对网络操作的中间结果或处理它们的重复代码不感兴趣,b) 块被保留,所以我得到更少的竞争条件,其中委托的某些方面被过早释放,并且 c) 我当特定操作完成时,永远不要混淆正在运行的代码。

简而言之,这是对 IMO NSURLConnection 接口的巨大改进。

于 2012-04-30T00:13:03.530 回答
2

这取决于。对于简单的事情,新的基于块的 API 让生活变得更轻松。但是,与实施这些NSURLConnectionDelegate方法相比,您会失去一些控制权。

例如,无法取消已使用此方法启动的连接,或在下载所有数据之前处理响应(例如用于解析标头)。

于 2012-04-30T00:39:09.073 回答
2

您也可以使用 GCD 在 iOS 4 上执行类似的操作。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{

    NSData *data = [NSURLConnection sendSynchronousRequest:blah returningResponse:response error:blah];
    //process response body here

    dispatch_async(dispatch_get_main_queue(), ^{

        //Update UI Code here
        self.textView.text = [[NSString alloc] initWithData:data];

    });
});

此代码和 OP 发布的代码的问题在于,一旦建立连接,您就无法取消它们。取消对 viewDidDisappear 的请求对提高应用程序的性能大有帮助。我在iOS PTL一书中广泛讨论了这个问题

您需要第三方网络框架(如 MKNetworkKit 或 RestKit 或现已失效的 ASIHTTP)的第二个原因是用于身份验证。大多数 Web 服务要求您使用 NSURLCredential(HTTP Basic 或 HTTP Digest 或 Windows NTLM 或 oAuth)进行身份验证

如果您推出自己的代码,仅此一项就需要几天时间。并不是说你不应该这样做。但是没有必要,因为所有这些第三方框架都被广泛使用,并且与您自己的代码相比,它们中的机会或错误或性能问题更少。

于 2012-04-30T03:33:46.727 回答
0

我写了一篇博文,比较了几种方法,包括NSURLConnectionAFNetworkingReactiveCocoa

ReactiveCocoa 方法

如果你想真正喜欢异步网络调用,你可以试试ReactiveCocoa。ReactiveCocoa 允许您定义代表每个网络请求的信号。它允许您链接多个相关的网络调用

#import <ReactiveCocoa/ReactiveCocoa.h>
// ...

-(RACSignal*)signalGetNetworkStep1 {
   NSURL* url = ...;
   return [RACSignal createSignal:^(RACDisposable *(id subscriber) {
      NSURLRequest *request1 = [NSURLRequest requestWithURL:url];
      AFJSONRequestOperation *operation1 = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
         [subscriber sendNext:JSON];
         [subscriber sendCompleted];
      } failure:^(AFHTTPRequestOperation *operation, NSError *error){
         [subscriber sendError:error];
      }];
      [operation1 start];
      return nil;
   }
}

-(void) yourMethod {
   [[self signalGetNetworkStep1] subscribeNext:^(id *x) {
      // perform your custom business logic
   }];
}
于 2013-08-05T05:19:23.890 回答