Какао Touch Вопрос. Должен ли [массив NSMutableArray] быть сохранен? - PullRequest
4 голосов
/ 13 июня 2009

Вот суть некоторого кода, который я пишу. Я обеспокоен тем, что неправильно решаю проблемы сохранения / выпуска с помощью метода класса массива в NSMutableArray. Следующее действительно утечка памяти?

for(a while) { 
    // do stuff
    NSMutableArray *a = nil;
    // do stuff
    if (!a) {
        a = [NSMutableArray array];
    }
} // for(a while)

Ответы [ 4 ]

12 голосов
/ 13 июня 2009

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

Большинство классов Какао предоставляют несколько способов создания нового объекта и очень соответствуют этому соглашению:

  1. [[NSSomeObject alloc] init]: вы ответственны за освобождение объекта (метод экземпляра).

  2. [NSSomeObject someObject]: объект будет автоматически освобожден для вас, обычно в конце цикла выполнения (метод класса). Это примерно эквивалентно [[[NSSomeObject alloc] init] autorelease].

Правильное использование метода экземпляра будет:

a = [[NSMutableArray alloc] init];
// do stuff
[a release];

Правильное использование метода класса будет:

a = [NSMutableArray array];
// do stuff, array is in the autorelease pool

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

6 голосов
/ 13 июня 2009

Из Правил управления памятью какао :

Вы становитесь владельцем объекта, если создаете его с помощью метода, имя которого начинается с «alloc» или «new» или содержит «copy» (например, alloc, newObject или mutableCopy), или если вы отправляете ему сохранить сообщение. Вы несете ответственность за отказ от владения принадлежащими вам объектами с помощью выпуска или автоматического выпуска. В любое другое время, когда вы получаете объект, вы не должны отпускать его.

Поэтому со строкой:

a = [NSMutableArray array];

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

2 голосов
/ 13 июня 2009

Да, если вы хотите, чтобы он остался.

Возвращенный объект является автоматически выпущенным объектом, который будет освобожден после очистки пула автоматического выпуска.

Все методы класса массива, начинающиеся с «массива», возвращают эти типы автоматически выпущенных объектов.

Прочтите это doc от Apple.

0 голосов
/ 18 ноября 2009

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

Существует соглашение:

  • префиксы init (init, initWithString :) указывают счет сохранения 1, где
  • префиксы имени объекта (string, stringWithString :) указывают на автоматически выпущенный объект

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

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