何时在NSURLConnection委托上调用发布?

时间:2009-10-27 16:46:47

标签: iphone ios delegates nsurlconnection

将委托传递给NSUrlConnection对象时,如下所示:

[[NSURLConnection alloc] initWithRequest:request delegate:handler];

什么时候应该给代表打电话?它应该在connectionDidFinishLoading吗?如果是这样,我会继续exec_bad_access。我看到我的代表正在通过工具泄漏。

由于

5 个答案:

答案 0 :(得分:6)

取自我的blog posthttp://i.ndigo.com.br/2012/01/releasing-nsurlconnection-and-its-delegate/


您必须特别注意委托对象,因为对于NSURLConnection,委托有一个特殊的考虑因素:它始终保留。

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/doc/uid/20001697-BAJDDIDG

  

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:DidFinishLoadingconnection: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];

这似乎已经在仪器中报告了内存泄漏。