这是参照的StackOverflow问题管理多个异步NSURLConnection的连接
我有在同一时间正在取得多个异步HTTP请求。 所有这些使用相同的NSURLConnection的委托功能。 (该receivedData对象是如在其它问题上述指定的每次连接不同,在该委托,我解析receivedDate对象,并且对这些解析串做额外的操作)
我的一切工作正常,到目前为止,但我不知道如果我需要做任何事情来确保正确的“多线程”的行为。
- 有没有可能是两个以上的连接将使用委托在同一时间? (我认为是)
- 如果是的话,它是如何解决的? (可可是否自动做到这一点?)
- 我是否需要有额外的检查,以确保每个请求的处理“正常”?
假设你推出的所有(异步)连接在单个线程,则委托全部邮件都会得到张贴在该线程的run loop。 因此,代表只需要能够应付一次被处理一个消息; 运行循环将在时间指针一个消息断。 这意味着,虽然委托消息的顺序是未知的,接下来的消息可能来自任何连接对象,会有你的委托方法没有并发执行。
但是,是你真正想使用在多个线程相同的委托对象,而不是仅仅使用API的异步性,那么你就需要处理并发的委托方法。
我增强了Three20库来实现,以获取数据,即使用户正在与UI打多个线程异步连接。 几个小时追逐下来CFNetwork框架内检测到的随机内存泄漏后,我终于根引起的问题。 我偶尔会失去跟踪的响应和数据。
其由多个线程存取的任何数据结构必须通过适当的锁来保护。 如果你不使用锁来访问相互排斥的方式共享数据结构,那么你是不是线程安全的。 请参阅“ 使用锁苹果的”部分线程编程指南 。
最好的解决办法是继承NSURLConnection的,并添加变量来保存其相关的响应和响应数据。 在每个连接的委托方法你再铸造NSURLConnection的到你的子类,并访问这些实例变量。 这是保证是相互排斥的,因为每个连接将利用其自身的响应和数据捆绑在一起。 我强烈建议尝试这个,因为它是最干净的解决方案。 下面是我实现的代码:
@interface TTURLConnection : NSURLConnection {
NSHTTPURLResponse* _response;
NSMutableData* _responseData;
}
@property(nonatomic,retain) NSHTTPURLResponse* response;
@property(nonatomic,retain) NSMutableData* responseData;
@end
@implementation TTURLConnection
@synthesize response = _response, responseData = _responseData;
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate {
NSAssert(self != nil, @"self is nil!");
// Initialize the ivars before initializing with the request
// because the connection is asynchronous and may start
// calling the delegates before we even return from this
// function.
self.response = nil;
self.responseData = nil;
self = [super initWithRequest:request delegate:delegate];
return self;
}
- (void)dealloc {
[self.response release];
[self.responseData release];
[super dealloc];
}
@end
/////////////////////////////////////////////////////////////////
////// NSURLConnectionDelegate
- (void)connection:(NSURLConnection*)connection
didReceiveResponse:(NSHTTPURLResponse*)response {
TTURLConnection* ttConnection = (TTURLConnection*)connection;
ttConnection.response = response;
ttConnection.responseData = [NSMutableData
dataWithCapacity:contentLength];
}
- (void)connection:(NSURLConnection*)connection
didReceiveData:(NSData*)data {
TTURLConnection* ttConnection = (TTURLConnection*)connection;
[ttConnection.responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
TTURLConnection* ttConnection = (TTURLConnection*)connection;
if (ttConnection.response.statusCode == 200) {
// Connection success
}
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error {
TTURLConnection* ttConnection = (TTURLConnection*)connection;
// Handle the error
}
是的,它可能有多个连接。 通知对象包含一个指向NSURLConnection
触发通知。
在内部我猜NSURLConnection
监听套接字和做这样的事情时有数据准备好。
[your_delegate
performSelectorOnMainThread:@selector(connectionCallback:)
withObject:self
waitUntilDone:NO];
所以你不必担心它被多线程的, NSURLConnection
将照顾这。 为简单起见我已经写了自我,在现实世界中一个NSNotification
对象中给出。
你不应该做与多线程任何检查。
文章来源: Cocoa: Checks required for multiple asynchronous NSURLConnections using same delegate functions?