2009-09-03 2 views
1

Это мой 'тик' функция:Deallocating NSMutableArray объекты

- (void) tick: (ccTime) dt 
{ 

NSLog(@"%d",ticker); 
if(fbut.Adown == YES && ticker > 4)//fbut is a button 
{ 


    elayer = [[effectsLayer alloc] init]; // each effectlayer draws a //projectile that moves forward 'x' ticks 

    elayer.e_playpos = glayer.playerpos; // player position 
    [self addChild:elayer z:2]; 

    [mutable addObject: elayer]; 
[elayer release]; 

    if(mutable.count > 20) // when there are 20 projectiles drawn, start //destroying the last one. 
    { 
    NSLog(@"mutable: %d", mutable.count); 

    [mutable removeLastObject]; 
    } 

    ticker=0; 
} 
ticker++; 


// . . . 

это то, что запущенная программа выглядит

http://screencast.com/t/LpNHL2kJIVpu

выглядит более чем на 20 ..

интересно Дело в том, что массив удерживается на 20 объектах. поэтому, если объекты «удаляются» (через [mutable removeLastObject];), как они появляются на экране?

Вот следующий рассол ...

Теперь я изменить инициализации, чтобы сохранить (обращайте внимание на ***** ы)

- (void) tick: (ccTime) dt 
{ 

NSLog(@"%d",ticker); 
if(fbut.Adown == YES && ticker > 4)//fbut is a button 
{ 


    elayer = [[effectsLayer alloc] retain]; // *********each effectlayer draws //a projectile that moves forward 'x' ticks 

    elayer.e_playpos = glayer.playerpos; // player position 
    [self addChild:elayer z:2]; 

    [mutable addObject: elayer]; 
[elayer release]; 

    if(mutable.count > 20) // when there are 20 projectiles drawn, start //destroying the last one. 
    { 
    NSLog(@"mutable: %d", mutable.count); 

    [mutable removeLastObject]; 
    } 

    ticker=0; 
} 
ticker++; 


// . . . 

И теперь нет эффекта слои не втягиваются, но все же NSArray содержит 21 - 20 объектов. все эти объекты неинициализированы. поэтому я добавил init до конца: elayer = [[[effectsLayer alloc] сохранить] init];

сейчас у меня такие же эффекты, как раньше.

так я стараюсь autorelease .. же эффект, много и много Pew Pew Pew лет, намного больше, чем 20.

моя цель состоит в том, чтобы только 20 допускаемых быть обращено в то время, и как только 20 являются они освобождаются. прямо сейчас, без освобождения, программа работает нормально, пока не будет около 4 минут, когда есть около 2000 e-слоев, а fps составляет около 5 ...

Почему корабль не скажет прямо?

(BTW я использую cocos2d рамки) это проект, который принадлежат мне, Алекс Эрли 2009.

ответ

7

Во-первых, [[effectsLayer alloc] retain] страшно. Никогда не делай этого. Когда-либо. Никогда не используйте выделенный объект, который не был инициализирован. Кроме того, это сохранит объект как минимум дважды, так как вызов + alloc возвращает сохраненный объект, и вы его снова сохраняете, а затем добавляете его в массив (который сохраняет его в третий раз), но это только дважды выпуская (когда он удаляется из массива и ваш единственный выпуск).

Я подозреваю, что проблема в этой строке: [self addChild:elayer z:2]; Что делает этот метод? Он отвечает за то, чтобы нарисовать элейер на экране? Если это так, то это означает, что он, вероятно, также сохраняет elayer, а это означает, что он не освобождается, потому что вы, похоже, не выполняете никакого вызова «removeChild» при выводе вещей из вашего изменяемого массива.

Вкратце: только потому, что что-то больше не находится в вашем массиве, это не значит, что это также не на экране.

+1

И даже если 'addChild: z:' не сохраняет объект, но каким-то образом сохраняет ссылку, это означает, что вы все еще добавляете слой в качестве дочернего элемента, но когда-нибудь он будет разбит, потому что это 'dealloc' редактор – Chuck

+0

@ Чак +1 очень прав. –

+1

Кроме того, если вы не сохранили его в 'addChild:', вы не будете ограничивать 20 пунктов, вы, скорее всего, потерпите крах. – bobDevil

Смежные вопросы