iPhone Cocos2d спрайтов в массиве, проблемы с памятью - PullRequest
3 голосов
/ 21 марта 2009

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

Я использую следующий код:

Sprite * Trees[50];
Layer * Forest;

Forest =  [Layer node];
Forest.isTouchEnabled = YES;
[self addChild:Forest z:30];

// do this a bunch of times
Trees[0] = [[Sprite spriteWithFile:@"mytree.png"] retain];
[Trees[0] setPosition:cpv(240,160)];
[Forest addChild:Trees[0] z:5];

А потом, когда я хочу уничтожить дерево, я использую:

[Forest removeChild:Trees[0] cleanup:YES];
[Trees[0] release];

Моя проблема в том, что когда я смотрю в Инструменты, я никогда не исправляю в этой памяти никогда не будет отступления. Я думал, что выпуск спрайта освободил бы память. Я делаю это совершенно неправильно?

Ответы [ 3 ]

4 голосов
/ 14 мая 2009

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

Здесь есть хорошая дискуссия о cocos2d и памяти.

Что я заметил, так это то, что все, что вы создаете и сохраняете, должно быть освобождено, но оно не будет освобождено из памяти, пока я не сделаю это:

[[TextureMgr sharedTextureMgr] removeAllTextures]; 

Это освободит память.

Вот более крупный пример:

Sprite * sPopup = [[Sprite spriteWithFile:@"popup.png"] retain];
    sPopup.position = cpv(240,440);
    [self addChild: sPopup z:2];
[sPopup release];

Тогда, когда я закончу с sPopup в другой функции, у меня будет это:

[[TextureMgr sharedTextureMgr] removeAllTextures]; 

и память освобождается.

3 голосов
/ 21 марта 2009

Я подозреваю, что вы "слишком" удерживаете:

Trees[0] = [[Sprite spriteWithFile:@"mytree.png"] retain];

Если Trees является локальной переменной в функции, вам не нужно сохранять ее в этом случае, если spriteWithFile возвращает Sprite с автоматическим выпуском.

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

При выдаче дополнительного сохранения, вероятно, ваш счет хранения всегда слишком велик (никогда не достигает 0), и, следовательно, ваш объект не является сборщиком мусора.

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

0 голосов
/ 11 апреля 2009

Даже если вы вызываете [Trees [x] release], я считаю, что вам все равно нужно «удалить» элемент из массива, например, Trees [x] = nil или что-то еще, поскольку сам массив все еще содержит объект.

«Сохранение» в создании «Спрайт» также не является необходимым, поскольку [Forest addChild: z:] также поместит сохранение в него (afaik).

...