将委托传递给NSUrlConnection
对象时,如下所示:
[[NSURLConnection alloc] initWithRequest:request delegate:handler];
什么时候应该给代表打电话?它应该在connectionDidFinishLoading
吗?如果是这样,我会继续exec_bad_access
。我看到我的代表正在通过工具泄漏。
由于
答案 0 :(得分:6)
取自我的blog post:http://i.ndigo.com.br/2012/01/releasing-nsurlconnection-and-its-delegate/
您必须特别注意委托对象,因为对于NSURLConnection
,委托有一个特殊的考虑因素:它始终保留。
initWithRequest:委托:
特别注意事项: 连接保留 代表。它何时释放代表 连接完成加载, 失败,或被取消。
因此,考虑到这一点,您有几个选项可以确保您的代理将被正确发布,我将尝试解释两个简单的代理。
第一个也是最常用的是使用初始化NSURLConnection的同一个类作为委托。
[[NSURLConnection alloc] initWithRequest:request self];
通过这样做,你的类在连接开始时保留计数将增加1,然后在连接完成加载,失败或被取消后减少1,导致没有内存泄漏。
第二个选项,即您尝试执行的操作,是使用另一个对象来处理所有连接调用。这也很好,但你需要额外注意记忆。解决问题的一个简单方法是使用自动释放对象初始化连接。
//creates the handler object
MyHandlerClass *handler = [[MyHandlerClass alloc] init];
//creates the connection with handler as an autorelease object
[[NSURLConnection alloc] initWithRequest:request delegate:[handler autorelease]];
OR 您可以在创建连接后立即释放您的处理程序(因为它已经被连接保留)
//creates the handler object
MyHandlerClass *handler = [[MyHandlerClass alloc] init];
//creates the connection with handler
[[NSURLConnection alloc] initWithRequest:request delegate:handler];
//releases handler object
[handler release];
两种方式都只使用连接类保留处理程序对象的所有权,连接类将在完成加载,失败或取消之后立即释放处理程序对象,再次导致没有内存泄漏。
编辑:通过执行上述任何选项,您无需担心在connection:DidFinishLoading
和connection:didFailWithError
方法中释放代理(但您仍需要释放连接)。
答案 1 :(得分:3)
这取决于handler
对象是什么以及如何使用它。例如,我通常使用self
作为我的代表:
[[NSURLConnection alloc] initWithRequest:request delegate:self];
我不需要在self
上调用版本,因为代理不会被保留,self
将被另一个对象释放。
如果handler
是一个新对象,那么你必须释放它(和connectionDidFinishLoading:应该没问题,除非你需要将handler
对象用于其他东西)。
您是否熟悉memory management in Cocoa的规则?
您能更好地了解对象handler
是什么以及您如何使用它?
答案 2 :(得分:0)
您需要释放连接,而不是代理。我认为NSURLConnection类不会保留委托,这就是为什么当你尝试发布它时会崩溃的原因。
释放连接的两个地方是连接:DidFinishLoading和connection:didFailWithError。
答案 3 :(得分:0)
NSURLConnection
代表被保留。
将ViewDidLoad
中的代码用于非ARC环境。
NSLog(@"Retain count %d",[self retainCount]);
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:nil delegate:self];
NSLog(@"Retain count %d",[self retainCount]);
答案 4 :(得分:-1)
对象处理程序用于实现connectionDidFinishLoading didReceiveData等。 我对很多Web服务进行了很多调用,而不是为每个Web服务创建一个对象,我有一个集中处理所有内容的类:
@interface DataService : NSObject {}
- (void) search:(NSString *) name byAddress:(NSString *)address;
@end
因此该方法的实现创建了传递的委托:
SearchDelegate *delegate = [[SearchDelegate alloc] init];
[self sendRequestToUrl:urlString withJson:jsonString andHandler:delegate];
我在仪器中看到的是SearchDelegate上存在内存泄漏...所以我认为它实际上是被保留了。
稍微修改一下我改变了我的sendRequestToUrlMethod以获得这个:
// http code setup blah...
[[NSURLConnection alloc] initWithRequest:request delegate:handler];
[handler release];
这似乎已经在仪器中报告了内存泄漏。