ОК, чтобы сохранить делегата ASIHTTPRequest? - PullRequest
0 голосов
/ 30 июня 2011

Можно ли сохранить делегата подкласса ASIHTTPRequest?

Я создал подкласс ASIHTTPRequest под названием JSONRequest. Каждый экземпляр JSONRequest является своим собственным делегатом, обрабатывает обратные вызовы и передает их в jsonDelegate, который является частным свойством JSONRequest, и отвечает на requestFinished:withResult:, где result является представлением NSDictionary ответ JSON. Для этого я перегрузил setDelegate: в JSONRequest, чтобы сделать super.delegate = self; self.jsonDelegate = newDelegate.

Можно ли сохранить jsonDelegate в этом случае, потому что часто jsonDelegate является контроллером представления, который иногда освобождается во время загрузки запроса, если пользователь нажимает «Назад», и т. Д. Я выпущу jsonDelegate в JSONRequest после вызова методов обратного вызова.

Откуда мне знать, что это нормально и не вызовет сохранения цикла .

Ответы [ 3 ]

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

Что удерживает запрос? (Операционная очередь, возможно? Кто знает?)

В общем, метод "выстрели и забудь и дай мне обратный вызов", который ты, похоже, предлагаешь, - плохая идея. Если ничто не удерживает VC отдельно от запроса, тогда (если структура вашего приложения не является немного глупой), VC никогда не будет ничего делать с данными, которые он получает, поэтому нет никаких оснований для его продолжения.

Это также кажется неправильным: имеет ли запрос VC, или VC владеет запросом? Я ожидаю последнего, поэтому VC также должен сохранить запрос.

Есть несколько исключений:

  • CAAnimation.delegate сохраняется, предположительно потому, что анимация в какой-то момент завершится (я не уверен, что произойдет, если это повторяющаяся анимация). То же самое может быть верно для делегата анимации UIKit
  • NSTimer сохраняет свою цель, вероятно, потому что NSInvocation делает. (Я написал класс «слабого таймера», чтобы обойти это.)
  • CADisplayLink сохраняет свою цель, предположительно похожую на NSTimer.

В этих случаях я часто работаю с классом «слабого прокси», который не сохраняет свою цель (и я написал обертки «слабого таймера» вокруг NSTimer / CADisplayLink, чтобы сделать это немного проще).

То, что вы должны сделать, это отслеживать запросы, которые вы инициировали, и в dealloc сделать что-то вроде

request.delegate = nil;
[request cancel];
self.request = nil;

Точно так же вы должны отменить регистрацию для уведомлений / действий / обратных вызовов KVO в соответствующее время. Есть исключение:

  • Если вы уверены, что он не отправит вам обратный вызов после того, как вы его отпустите, вам не нужно об этом беспокоиться, поэтому делегаты текстовых полей и действия / цели кнопки не нужно очищать.

Есть исключения из исключения:

  • UIWebView (по крайней мере, в старых ОС) также сохраняется чем-то другим, возможно, чем-то связанным с веб-потоком. Может произойти сбой, если VC исчезает, когда веб-представление все еще загружается.
  • Обратные вызовы прокрутки UIScrollView также приводят к тому, что представление сохраняется после срока службы VC. Вы можете проверить это, например, удерживая нажатой кнопку «Готово» и начиная щелчок «Готово».
2 голосов
/ 30 июня 2011

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

В этом случае цикл сохранения всегда будет прерываться в какой-то момент.

1 голос
/ 04 мая 2012

Я знаю, что этот вопрос изначально касается ASIHTTPRequest, но люди могут наткнуться на этот поток, и это может заставить их подумать, что использование ASIHTTPRequest все еще является наилучшей практикой - это не так, разработка Infact в 2011 году остановлена.

Используя более современные библиотеки HTTP, которые по умолчанию используют блоки (я предпочитаю AFNetworking ), все переменные, на которые ссылаются блоки сбоя / успеха, либо копируются, либо сохраняются до тех пор, пока блоки не будут освобождены. Это избавит вас от головной боли при управлении памятью - кроме случаев, когда вы используете self в одном из блоков, вы создадите цикл сохранения до тех пор, пока блоки не будут освобождены.

...