Pla*_*mer 9 cocoa multithreading objective-c nsurlconnection
这是参考StackOverflow问题管理多个异步NSURLConnection连接
我有多个异步HTTP请求同时发出.所有这些都使用相同的NSURLConnection委托函数.(对于每个连接,receivedData对象在上面的另一个问题中指定的不同.在委托中,我解析receivedDate对象,并对这些解析的字符串执行其他操作)
到目前为止,一切正常,但我不确定是否需要做任何事情以确保正确的"多线程"行为.
Jam*_*ald 19
我增强了Three20库以实现跨多个线程的异步连接,以便即使用户正在使用UI来获取数据.经过几个小时追逐在CFNetwork框架内检测到的随机内存泄漏,我终于根本导致了这个问题.我偶尔会失去对回复和数据的追踪.
必须通过适当的锁保护由多个线程访问的任何数据结构.如果您没有使用锁以互斥的方式访问共享数据结构,那么您就不是线程安全的.请参阅Apple的线程编程指南的" 使用锁定 "部分.
最好的解决方案是子类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
}
Run Code Online (Sandbox Code Playgroud)
小智 13
假设您在单个线程上启动所有(异步)连接,那么委托消息将全部发布在该线程的运行循环中.因此,代表只需要能够处理一次处理的一条消息; 运行循环将一次关闭一条消息.这意味着虽然委托消息的顺序是未知的,并且下一条消息可能来自任何连接对象,但是不会同时执行委托方法.
但是,如果您实际上尝试跨多个线程使用相同的委托对象,而不是仅仅使用API的异步性质,那么您将需要处理并发委托方法.
归档时间: |
|
查看次数: |
8674 次 |
最近记录: |