Плохая практика удерживать себя? - PullRequest
7 голосов
/ 17 октября 2010

У меня есть простой запрос, который кто-то хотел бы прояснить ... Это плохая практика - сохранять себя?

У меня есть объект запроса к серверу, который я хотел бы сделать. Я хотел бы иметь возможность использовать его следующим образом:

ARequest *request = [ARequest request: someParam];
request.delegate = self;
[request begin];

Чтобы объект не самоуничтожился, как только пул авто-выпуска истощается, я думаю, что мне нужно вызвать метод retain в его методе init, а затем в Release, когда ответ сервера получен, обработан и доставлен на делегировать.

Однако что-то поднимает предупреждающий звонок в моей голове при таком подходе. Лучшие способы сделать это?

Ответы [ 4 ]

6 голосов
/ 18 октября 2010

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

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

2 голосов
/ 17 октября 2010

Это не неслыханно, но несколько необычно.Основной способ, которым я видел, что он использовал (и использовал его сам), - это когда вы имеете дело с каким-то полусинхронным объектом (под полусинхронным я имею в виду, что он не блокирует основной поток, но также невыполнить в фоновом потоке; NSURLConnection будет соответствовать этому счету).Например, я написал подкласс NSWindowController, специально предназначенный для отображения окна в виде листа и для вызова некоторых обратных вызовов делегата.По сути, вы бы alloc / init создали новый контроллер листов и вызвали бы beginSheetForWindow:.Это будет запускать лист полусинхронно, а затем вызывать соответствующий обратный вызов, когда лист будет отклонен.

Поскольку вызывающий объект не обязательно «владеет» листом (думайте о нем как о версии Mac дляконтроллер модального представления на iOS), контроллер листа делает [self retain] непосредственно перед показом листа и [self release] сразу после очистки и вызова обратных вызовов.Цель этого состояла в том, чтобы гарантировать, что объект controller будет держаться до тех пор, пока лист не будет готов.(Лист, IIRC, был сохранен runloop, но мне также нужно было, чтобы контроллер оставался там)

Как я уже говорил, очень редко можно встретить ситуацию, когда вы захотите [self retain], ноэто не невозможноОднако, как правило, если вы считаете, что вам нужно [self retain], вы можете подумать еще раз.

1 голос
/ 17 октября 2010

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

Является ли ARequest классом, который вы создали? Создает ли он новый поток для асинхронной отправки запроса?

0 голосов
/ 17 октября 2010

Я однажды сделал то же самое, что и ты. Я написал Category-Method для NSString, чтобы отправить его на сервер, который распечатает его. В Category-методе мне пришлось вызывать [self retain], чтобы методы обратного вызова могли быть NSString-Categoryroy-Method to.
Я чувствовал себя так плохо из-за этого, что переписал все, чтобы использовать Singleton, доступ к которому осуществляется с помощью Category-Method. Таким образом, синглтон будет сохранять строку столько, сколько необходимо.

...