NSURLConnection是否会保留它的代理?

23

我的问题概述: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必须对其委托进行保留,但我在文档中没有看到任何内容。有人有想法吗?
3个回答

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:可以清晰地看到"self"的保留计数确实增加了+1。如果你感觉勇敢并想要挑战EXC_BAD_ACCESS神,可以添加

[conn dealloc];
NSLog(@"Retain count after dealloc: %d", [self retainCount]);

这将再次打印出“1”,显示后处理减量。但是,您将收到一个很好的程序接收信号:“EXC_BAD_ACCESS”,因为NSAutoreleasePool将尝试释放连接,而它已经不存在了;)


1
好问题和好答案。我自己也在苦苦挣扎,但我决定在委托分配之后立即添加[self release]以平衡保留计数。由于self是我的类中的委托,我认为没有理由增加它的保留计数。如果这是不正确的,请有人告诉我。 - jocull
我只想补充一句 - 谢谢。《缺失的手册》第327部分。令人难以置信的是,这种有点重要的事实在苹果文档中没有提到。我以为它会被保留,但不确定,文档对此没有任何说明,在Cocoa框架中,许多情况下委托被保留,但这是个例外。 - n13

9
大多数委托属性都不会被保留,而是被分配以防止循环引用。有关此问题,请参见this的问题。
然而,NSUrlConnection没有特定的委托属性。您必须在连接初始化时指定委托。我认为这就是为什么它会接收到一个保留的对象,正如Dave Martorana展示的那样。

7

1
好的,这是关于NSURLConnection的“注释”。尽管如此,由于它非常重要,仍应在方法描述中提到它。 - n13

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接