我正在使用Master Detail Controller。在主列表中有5个项目。在选择每个项目时,会进行异步调用。
有一个SingleTon类,可以处理所有网络调用。
[[MyNetwokCommunication connectionInstance]
makeRequest:"url1" delegate:self];
[[MyNetwokCommunication connectionInstance] makeRequest:"url2" delegate:self];
makeRequest:delegate:
中的实际实施是[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediatley:YES]
。
所以,这是处理单例类网络连接的正确方法,因为它可能会覆盖一个请求的数据部分与另一个请求。
答案 0 :(得分:1)
有很多方法可以解决这个问题。不幸的是,NSURLConnection无法用作字典中的键,这使得生活特别悲惨。
最好的办法,假设你还不需要支持iOS 6及更早版本(或OS X v10.8或更早版本),那就是放弃NSURLConnection for NSURLSession。然后使用基于块的调用来发出请求并处理响应。与NSURLConnection对象不同,您可以使用NSURLSessionTask对象作为字典键,这样可以轻松跟踪哪些数据来自哪个请求,以及存储与该请求关联的其他对象或其他数据(例如,将UI单元存储在数据所在的位置)去)。
如果必须使用NSURLConnection来支持较旧的操作系统,则可以考虑继承NSURLRequest并添加额外数据。请注意,这种替代方法不使用NSURLSession,并且您需要提供自己的重定向处理程序,因为否则每当重定向发生时您最终都会返回通用NSURLRequest对象,IIRC。或者,您可以在连接对象上添加Objective-C关联对象。 (至少我99%肯定这是有效的。)
答案 1 :(得分:0)
那不是我怎么做的。
iOS上用于序列化事物的最佳范例是NSOperationQueue。您可以创建并发为1的队列,然后将NSURLConnection或NSURLSession子项排队为NSOperations。
这使您可以做一些巧妙的事情,比如创建依赖于其他操作成功的操作。
这里是队列的创建:
@property (strong, nonatomic) NSOperationQueue *queue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_queue = [[NSOperationQueue alloc] init];
[_queue setMaxConcurrentOperationCount:1];
});
然后创建网络操作:
// HTTPOperation.h
#import <Foundation/Foundation.h>
@interface HTTPOperation : NSOperation
@end
//
// HTTPOperation.m
//
#import "HTTPOperation.h"
@implementation HTTPOperation
- (void) main
{
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
if (error == nil)
{
// Parse data here
NSLog(@"Completed successfully");
}
}
@end
执行操作:
- (IBAction)queueHTTP {
HTTPOperation *op = [HTTPOperation new];
[self.queue addOperation:op];
}
您可以从任何地方排队任意数量,它们将按顺序执行。我建议观看高级NSOperations上的WWDC视频:
https://developer.apple.com/videos/wwdc/2015/?id=226
这是非常有益的。