我的问题摘要:NSURLConnection是否保留其委托?
详细问题和方案:
我有一个名为JsonDownloader的自定义类,它接受一个URL并返回一个URL返回的JSON的NSDictionary。
在iPhone应用程序上,我做了类似的事情。 (init方法启动整个过程)
- (void)viewDidLoad {
JsonDownloder *temp = [[[JsonDownloader alloc] initWithURL:urlString returnDataTo:self]];
[temp release];
[super viewDidLoad];
}
当JsonDownloader完成下载和解析时,它会对returnDataTo:对象执行回调,在本例中为调用对象。
这很好用。即使我在Web服务器响应中引入了30秒的延迟,JsonDownloader仍然存在,并且正确回调。
所以我的问题是这样的:什么让JsonDownloader保持超越事件周期的结束?我明确地发布了它。
我的预感是NSURLConnection必须对其委托进行保留,但我没有在文档中看到任何内容。有人有想法吗?
答案 0 :(得分:25)
没有很多setter不会复制或保留传递给它的变量,以免在保留计数达到零时将所述变量的内存重新分配给其他内容。
然而,答案是肯定的,确实如此。一些测试代码显示代表的保留计数上升:
NSLog(@"Retain count before: %d", [self retainCount]);
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];
NSURLConnection* conn = [NSURLConnection connectionWithRequest:request delegate:self];
NSLog(@"Retain count after: %d", [self retainCount]);
在日志中生成:
Running…
2009-07-09 02:13:40.516 delegateRetain[45123:a0f] Retain count before: 1
2009-07-09 02:13:40.525 delegateRetain[45123:a0f] Retain count after: 2
Debugger stopped.
所以你可以清楚地看到connectionWithRequest:delegate:
中的“自我”确实其保留计数增加了+1。如果你觉得自己很勇敢并且想要使用EXC_BAD_ACCESS诸神,请加入
[conn dealloc];
NSLog(@"Retain count after dealloc: %d", [self retainCount]);
将再次打印出“1”,显示一个dealloc减少后的值。但是,你会得到一个不错的Program received signal: “EXC_BAD_ACCESS”.
,因为NSAutoreleasePool
将尝试释放连接,它将会消失;)
答案 1 :(得分:9)
大多数代表属性不会被保留,但会被分配以防止循环引用。有关这方面的问题,请参阅this。
但是,NSUrlConnection没有特定的委托属性。您必须指定委托以及连接的初始化。我认为这就是为什么它确实得到了保留,正如Dave Martorana所示。
答案 2 :(得分:7)
是的,“连接保留委托。它在连接完成加载,失败或被取消时释放委托”,根据特殊注意事项下的Xcode Documentation for -[NSURLConnection initWithRequest:delegate:]
。另见:NSURLConnection inherent memory leak?