将委托传递给NSUrlConnection
对象时,如下所示:
[[NSURLConnection alloc] initWithRequest:request delegate:handler];
你什么时候应该在委托上调用释放?应该在connectionDidFinishLoading
吗?如果是这样,我不断得到exec_bad_access
. 我看到我的代表正在通过仪器泄漏。
谢谢
将委托传递给NSUrlConnection
对象时,如下所示:
[[NSURLConnection alloc] initWithRequest:request delegate:handler];
你什么时候应该在委托上调用释放?应该在connectionDidFinishLoading
吗?如果是这样,我不断得到exec_bad_access
. 我看到我的代表正在通过仪器泄漏。
谢谢
取自我的博客文章:http : //i.ndigo.com.br/2012/01/releasing-nsurlconnection-and-its-delegate/
您必须特别注意委托对象,因为对于委托NSURLConnection
有一个特殊的考虑:它始终被保留。
initWithRequest:delegate :
特别注意事项:连接保留委托。当连接完成加载、失败或被取消时,它会释放委托。
因此,考虑到这一点,您有多种选择来确保您的代表将被正确释放,我将尝试解释 2 个简单的选择。
第一个也是最常用的,是使用初始化 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]];
或者您可以在创建连接后立即释放您的处理程序(因为它已被连接保留)
//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
方法中释放委托(但您仍然必须释放连接)。
这将取决于对象handler
是什么以及您如何使用它。例如,我通常self
用作我的代表:
[[NSURLConnection alloc] initWithRequest:request delegate:self];
我不需要调用 release,self
因为委托没有保留,self
将被另一个对象释放。
如果handler
是一个新对象,那么您将不得不释放它(并且 connectionDidFinishLoading: 应该没问题,除非您需要将该handler
对象用于其他用途)。
你熟悉Cocoa 中的内存管理规则吗?
您能否更好地了解对象handler
是什么以及如何使用它?
Your need to release the connection, not the delegate. The NSURLConnection class I think does not retain the delegate, which is why you get a crash when you try and release it.
The two places to release the connection are connection:DidFinishLoading, and connection:didFailWithError.
NSURLConnection
代表被保留。
ViewDidLoad
在非 ARC 环境中使用代码。
NSLog(@"Retain count %d",[self retainCount]);
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:nil delegate:self];
NSLog(@"Retain count %d",[self retainCount]);
对象处理程序用于实现 connectionDidFinishLoading didReceiveData 等。我对许多 Web 服务进行了很多调用,而不是为每个服务创建一个对象,而是为所有这些东西创建了一个中心类:
@interface DataService : NSObject {}
- (void) search:(NSString *) name byAddress:(NSString *)address;
@end
因此该方法的实现创建了要传递的委托:
SearchDelegate *delegate = [[SearchDelegate alloc] init];
[self sendRequestToUrl:urlString withJson:jsonString andHandler:delegate];
我在 Instruments 中看到的是 SearchDelegate 上存在内存泄漏......所以我认为它实际上是被保留的。
修修补补了一下,我改变了我的 sendRequestToUrlMethod 有这个:
// http code setup blah...
[[NSURLConnection alloc] initWithRequest:request delegate:handler];
[handler release];
这似乎已经摆脱了 Instruments 中报告的内存泄漏。