Авто-релиз управления памятью против вопроса распределения - PullRequest
0 голосов
/ 14 августа 2010

3 взаимосвязанных вопроса:

1. Предоставляют ли приведенные ниже фрагменты кода те же самые результаты с точки зрения памяти?

NSBundle *bundle=[[NSBundle alloc] init];
[bundle release];
bundle=nil;

и

NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
NSBundle *bundle=[NSBundle mainBundle];
[pool drain];
pool=nil;
bundle=nil;

2. Почему в

NSBundle *bundle=[[NSBundle alloc] init];
[bundle release];

значение retainCount пакета равно 1, а не 0?

3. Что рекомендуется: всегда использовать методы класса или всегда приобретать права владения с помощью alloc?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 14 августа 2010
  1. Да, они должны быть эквивалентны с точки зрения управления памятью, с точки зрения разработчика.Фреймворки могут что-то делать за сценой, чтобы держаться за [NSBundle mainBundle], но это не ваше дело.

  2. Игнорировать retainCount. машет рукой Это не тот метод, который вы ищете.Как только вы отказались от владения объектом, вызвав release или autorelease, отправлять больше сообщений этому объекту недопустимо (плохая практика).В вашем примере вы alloc и NSBundle, так что вы им владеете.Это означает, что он имеет счет удержания +1 (я говорю +1, потому что он относительный).Когда вы освобождаете пакет, он теперь имеет счет «0», что означает, что вы больше не являетесь владельцем этого объекта (несмотря на то, может ли он все еще существовать в памяти), что означает, что вы должны не отправлять сообщенияк этому, под страхом штрафа, взрывающегося в ваше лицо.

  3. Рекомендуется использовать все, что подходит для ситуации.Если вам нужен только временный объект, то использование метода класса, который возвращает автоматически освобожденный объект, вероятно, будет вполне приемлемым.Если вам нужно быть абсолютно уверенным, что объект не исчезнет во время его использования, тогда вы можете использовать подход alloc / init (или retain объект с автоматическим выпуском), а затем просто release это когда вы закончите.

1 голос
/ 14 августа 2010
  1. Во втором примере вы создадите 1 дополнительный объект (NSAutorealeasePool), и из-за этого два не точно одинаковы с точки зрения памяти.Но после запуска кода я верю, что память вернется в одно и то же состояние в обоих примерах.Я не совсем уверен, но я верю, что во втором примере bundle - объект с автоматическим выпуском, поэтому, когда пул очищается, он освобождается.

  2. Я полагаю, что когда объект получаетВ dealloc'е retainCount не изменилось.

  3. Обычно рекомендуется избегать методов класса при создании большого количества временных объектов, поскольку они не будут освобождены до следующего стока AutoreleasePool.вызывается (и если у вас нет AutoreleasePool внутри вашего метода, это не произойдет наверняка, пока вы не вернетесь из своего метода - и, возможно, даже позже).В противном случае вы должны использовать тот, который чувствует себя лучше для вас.Я лично предпочитаю размещать их.Также важно помнить, что если вы хотите, чтобы автоматически освобожденный объект (объект, возвращенный из метода класса) оставался без изменений, даже после того, как вы вернулись из функции, чтобы сохранить его.

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