iOS - Вопрос об управлении памятью: случай NSArray - PullRequest
1 голос
/ 27 июля 2011

У меня есть этот код:

- (void) firstMethod{
NSString *first = @"Hello";
NSString *second = @"World";
NSArray *myFirstArray = [[NSArray alloc] initWithObjects: first, second, nil];
[mySecondArray addObject :myFirstArray];
[myFirstArray release];
}

, когда я выпускаю myFirstArray, могу ли я потерять две строки?или они сохраняются в mySecondArray?

Ответы [ 2 ]

3 голосов
/ 27 июля 2011

Первый и второй имеют счет сохранения 1 (сделан авто-релиз) при создании объектов.
Каждый объект, добавленный в массив, имеет увеличенный счетчик сохранения.

Таким образом, при добавлении first и second к firstArray их счетчик хранения увеличивается до 2 (с 1 из autorelease). При добавлении этих объектов из firstArray в secondArray, ничего не происходит с firstArray, но first и second обнаруживаются в firstArray и снова добавляются в secondArray, поэтому их счет сохранения снова увеличивается до 3 (включая 1 из автоматического выпуска).

Если вы выпускаете первый массив, его собственный счетчик хранения уменьшается, и у каждого объекта, который он «содержит», также уменьшается счетчик хранения. Таким образом, массив имеет счет сохранения в 0 и удаляется из памяти. У первого и второго количество сохраняемых счетчиков уменьшилось до 2 (включая 1 ауто-релиза).

Если вы подождете некоторое время, сработает эффект автоматического выпуска, и для первого и второго счетчик их сохранения уменьшится на 1, поэтому у них будет счетчик хранения 1, который был установлен при добавлении первого и второго из firstArray в secondArray.

Просто сохраните в памяти, что массив не содержит никаких объектов, но ссылается (указатели, если вы предпочитаете) на объекты, которые находятся вне массива.

если вы напишите:

NSArray *myFirstArray = [[NSArray alloc] initWithObjects: @"test1", nil];

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

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

РЕДАКТИРОВАТЬ : данное описание дано для addObjectsFromArray:
Я прочитал еще раз вопрос, и я вижу, что вопрос для addObject:

Так что рецепт такой же. Предположим, что счетчик удержания указан в скобках, а AR означает аутрелиз:

NSString *first = @"Hello";
NSString *second = @"World";

первый (1 AR)
второй (1 AR)

NSArray *myFirstArray = [[NSArray alloc] initWithObjects: first, second, nil];

myFirstArray (1)
первый (1 AR + 1)
второй (1 AR + 1)

[mySecondArray addObject :myFirstArray];

mySecondArray (1 AR, при условии, что он создан с [массивом NSMutableArray]; отсутствует)
myFirstArray (1 + 1) сохраняется вызовом
первая (1 AR + 1) без изменений
секунда (1 AR + 1) без изменений

[myFirstArray release];

mySecondArray (1 AR) без изменений
myFirstArray (1) -1, но все еще живет
первая (1 AR + 1) без изменений
секунда (1 AR + 1) без изменений

Надеюсь, это понятно: -)

Представим, что Вы подождете некоторое время.

  • Запущен авто-выпуск mySecondArray:
    mySecondArray (0) KILL

  • тогда myFirstArray получит релиз
    myFirstArray (0) KILL

  • тогда каждый объект в myFirstArray получает релиз
    первый (1 AR) -1, но все еще живет короткое время
    секунда (1 AR) -1, но все еще живущая короткое время

  • Подождите некоторое время для следующего цикла обработки событий, после чего будет запущено автоматическое освобождение строк:
    первый (0) УБИЙ
    секунда (0) KILL

1 голос
/ 27 июля 2011

Они не хранятся во втором массиве, но ваш первый массив будет сохранен во втором массиве.

То есть, когда вы вызываете release для первого массива, он не будет освобожден, пока массив не будет удален из второго массива.

Второй массив сохраняет первый массив. Первый массив сохраняет строки.

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