Подтвердить что ты не робот

Сохраняет ли NSURLConnection свой делегат?

Резюме моего вопроса: сохраняет ли 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 должен делать удержание на своем делете, но я ничего не видел в документации. У кого-нибудь есть идеи?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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