Сохраняет ли NSURLConnection свой делегат? - PullRequest
23 голосов
/ 09 июля 2009

Резюме моего вопроса: сохраняет ли NSURLConnection своего делегата?

Подробный вопрос и сценарий:

У меня есть собственный класс, называемый JsonDownloader, который берет URL и возвращает NSDictionary JSON, который возвращает URL.

В приложении для iPhone я делаю что-то подобное. (метод init запускает весь процесс)

- (void)viewDidLoad {
    JsonDownloder *temp = [[[JsonDownloader alloc] initWithURL:urlString returnDataTo:self]];
    [temp release];
    [super viewDidLoad];
}

Когда JsonDownloader завершает загрузку и анализ, он выполняет обратный вызов объекта returnDataTo: в данном случае вызывающего объекта.

Это работает просто отлично. Даже если я введу 30-секундную задержку в ответе своего веб-сервера, JsonDownloader все еще существует и правильно выполняет обратный вызов.

Итак, мои вопросы таковы: что удерживает JsonDownloader после окончания цикла событий? Я явно выпускаю это.

Я догадываюсь, что NSURLConnection должен сохранить своего делегата, но я ничего не увидел в документации. У кого-нибудь есть идеи?

Ответы [ 3 ]

25 голосов
/ 09 июля 2009

Не так много сеттеров, которые не копируют и не сохраняют переменную, передаваемую ей, чтобы память упомянутой переменной не была перераспределена чему-либо еще, когда ее счетчик сохранения достигнет нуля.

Однако, ответ ДА, так и есть. Небольшой тестовый код показывает, что количество сохраняемых делегатов увеличилось:

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», показывая декремент после освобождения. Тем не менее, вы получите хороший Program received signal: “EXC_BAD_ACCESS”., потому что NSAutoreleasePool попытается разорвать соединение, и оно пропадет;)

9 голосов
/ 09 июля 2009

Большинство делегатов свойства не сохраняются, а назначаются для предотвращения циклических ссылок. См. Также этот вопрос об этом.

Однако NSUrlConnection не имеет определенного свойства делегата. Вы должны указать делегата вместе с инициализацией соединения. Я думаю, именно поэтому он получает удержание, как показал Дейв Марторана.

7 голосов
/ 30 июня 2011

Да, «Соединение сохраняет делегата. Оно освобождает делегата, когда соединение заканчивает загрузку, не удается или отменено», в соответствии с Документацией XCode для -[NSURLConnection initWithRequest:delegate:] в разделе Особые соображения. См. Также: Утечка памяти, присущая NSURLConnection?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...