асинхронные запросы с NSURLConnection: когда выпустить - PullRequest
0 голосов
/ 06 февраля 2011

Руководство Apple очень конкретно относится к освобождению объекта подключения: это делается в didFailWithError и connectionDidFinishLoading.

Однако, когда я делаю то же самое, я позже получаю это в зомби-mode

*** -[NSURLConnection releaseDelegate]: message sent to deallocated instance 0x1001045b0

Кажется, в AppKit есть какой-то код, который освобождает меня от соединения.

Я был бы рад предположить, что руководство Apple неверно, но не хочу получатькакая-то ужасная утечка памяти или незначительная несовместимость со старыми версиями OSX или что-то в этом роде.

Безопасно ли игнорировать документацию в этом случае?

edit
Запрос на создание кода

  URLConnectionDelegate *delegate = [[URLConnectionDelegate alloc] initWithSuccessHandler:^(NSData *response) {
      ...
  }];
  [NSURLConnection connectionWithRequest:request delegate:delegate];  

  // I do not release delegate when testing for this issue, not sure whether I should in general

Сам класс делегата

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
  successHandler(receivedData);

  [receivedData release];
  Block_release(successHandler);

  // do we really need this????????
  [connection release];
}

1 Ответ

3 голосов
/ 06 февраля 2011

Поскольку вы создали соединение с

[NSURLConnection connectionWithRequest:request delegate:delegate]; 

у вас нет этого объекта подключения, поэтому вы не должны освобождать его.

Как говорится, я бы не рекомендовал это. Если у вас нет объекта, у вас нет гарантии, что он переживет циклы истощения пула автоматического освобождения, т. Е. Может случиться, что ваш объект соединения (авто) освобождается до его полной загрузки. Вместо этого создайте объявленное свойство retain для хранения соединения:

@property (retain) NSURLConnection *connection;

назначить объект подключения объявленному свойству:

self.connection = [NSURLConnection connectionWithRequest:request
    delegate:delegate]; 

и после завершения загрузки или сбоя соединения освободите его, присвоив объявленному свойству nil:

self.connection = nil;

Что касается вашего делегата, если он должен существовать только во время загрузки соединения, вы можете автоматически выпустить его, так как соединение сохраняет делегата:

URLConnectionDelegate *delegate = [[[URLConnectionDelegate alloc]
    initWithSuccessHandler:^(NSData *response) {
    // …
}] autorelease];

self.connection = [NSURLConnection connectionWithRequest:request
    delegate:delegate]; 
...