Objective c Cocoa:是否需要检查使用相同委托函数的多个异步NSURLConnection?

Objective c Cocoa:是否需要检查使用相同委托函数的多个异步NSURLConnection?,objective-c,cocoa,multithreading,nsurlconnection,Objective C,Cocoa,Multithreading,Nsurlconnection,这是关于StackOverflow问题的 我同时发出了多个异步HTTP请求。所有这些都使用相同的NSURLConnection委托函数。(如上面的另一个问题所述,每个连接的receivedData对象都不同。在委托中,我解析receivedDate对象,并对解析的字符串执行其他操作) 到目前为止,一切都很好,但我不确定是否需要做任何事情来确保正确的“多线程”行为 是否可能有两个以上的连接同时使用该委托?(我想是的) 如果是,如何解决?(Cocoa是否自动执行此操作?) 我是否需要进行额外检查以

这是关于StackOverflow问题的

我同时发出了多个异步HTTP请求。所有这些都使用相同的NSURLConnection委托函数。(如上面的另一个问题所述,每个连接的receivedData对象都不同。在委托中,我解析receivedDate对象,并对解析的字符串执行其他操作)

到目前为止,一切都很好,但我不确定是否需要做任何事情来确保正确的“多线程”行为

  • 是否可能有两个以上的连接同时使用该委托?(我想是的)
  • 如果是,如何解决?(Cocoa是否自动执行此操作?)
  • 我是否需要进行额外检查以确保每个请求都得到“正确”处理

假设您在单个线程上启动所有(异步)连接,那么委托消息将全部发布在该线程的运行循环中。因此,代理只需要能够一次处理一条消息;运行循环将一次传递一条消息。这意味着,虽然委托消息的顺序未知,并且下一条消息可能来自任何连接对象,但委托方法不会同时执行


但是,如果您实际上试图跨多个线程使用相同的委托对象,而不仅仅是使用API的异步特性,那么您将需要处理并发委托方法。

是的,可能有多个连接。通知对象包含指向触发通知的
NSURLConnection
的指针

在内部,我猜
NSURLConnection
侦听套接字,并在数据就绪时执行类似操作

[your_delegate 
    performSelectorOnMainThread:@selector(connectionCallback:) 
    withObject:self 
    waitUntilDone:NO];
因此,您不必担心它是多线程的,
NSURLConnection
将解决这个问题。为了简单起见,我编写了self,在现实世界中,给出了一个
NSNotification
对象


您不必执行任何与多线程相关的检查。

我增强了Three20库,以实现跨多个线程的异步连接,以便即使用户正在玩UI也能获取数据。经过数小时的追踪,在cfnetworkframework中检测到的随机内存泄漏最终由root引起。我偶尔会忘记回答和数据

由多个线程访问的任何数据结构都必须受到适当的锁的保护。如果您没有使用锁以互斥的方式访问共享数据结构,那么您就不是线程安全的。请参阅苹果公司手册的“”部分

最好的解决方案是将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
}

谢谢你的建议,我相信这是最有效的处理方法。我很惊讶这么多年之后,苹果还没有将NSMutableData*与NSURLConnection结合起来。我看不出他们有什么理由不这样做。这是相当标准的操作,你说呢?