在我所见的任何地方,我都看到人们明确地使用队列或运行循环来进行网络操作。我应该在 iOS 5 中仍然这样做,还是应该NSURLConnection sendAsynchronousRequest:queue:completionHandler:
改用?这是在 iOS >= 5 中进行网络操作的首选方法吗?
4 回答
我无法回答其他人的偏好,但我推出了自己的< os5,并且我非常喜欢块操作。a) 我对网络操作的中间结果或处理它们的重复代码不感兴趣,b) 块被保留,所以我得到更少的竞争条件,其中委托的某些方面被过早释放,并且 c) 我当特定操作完成时,永远不要混淆正在运行的代码。
简而言之,这是对 IMO NSURLConnection 接口的巨大改进。
这取决于。对于简单的事情,新的基于块的 API 让生活变得更轻松。但是,与实施这些NSURLConnectionDelegate
方法相比,您会失去一些控制权。
例如,无法取消已使用此方法启动的连接,或在下载所有数据之前处理响应(例如用于解析标头)。
您也可以使用 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)进行身份验证
如果您推出自己的代码,仅此一项就需要几天时间。并不是说你不应该这样做。但是没有必要,因为所有这些第三方框架都被广泛使用,并且与您自己的代码相比,它们中的机会或错误或性能问题更少。
我写了一篇博文,比较了几种方法,包括NSURLConnection、AFNetworking和ReactiveCocoa。
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
}];
}