2009-09-03 7 views
1

Ceci est ma fonction 'tick':objets Désallocation 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++; 


// . . . 

c'est ce que le programme en cours ressemble

http://screencast.com/t/LpNHL2kJIVpu

ressemble à plus de 20 ..

intéressant chose cependant, c'est que le tableau se maintient à 20 objets. donc si les objets sont 'supprimés' (via [mutable removeLastObject];) comment se fait-il qu'ils apparaissent sur l'écran?

est ici le cornichon suivant ...

Maintenant je changer pour conserver initialisation (cherchez le ***** 's)

- (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++; 


// . . . 

Et maintenant, aucune couche d'effet sont en cours d'élaboration, mais le NSArray contient toujours 21 à 20 objets. tous ces objets ne sont pas initialisés. donc j'ai ajouté init à la fin: elayer = [[[effetsLayer alloc] retain] init];

maintenant j'ai les mêmes effets d'avant.

donc j'essayer autorelease .. même effet, beaucoup et beaucoup de Pew Pew Pew, de manière plus que 20.

mon objectif est d'avoir seulement 20 alowed à tirer à un moment et une fois que les 20 sont attirés, ils sont libérés. En ce moment, sans désallocation, le programme fonctionne ok jusqu'à environ 4 minutes quand il y a environ 2000 couches e et le fps est d'environ 5 ..

pourquoi le navire ne pew pew droit?

(BTW i m à l'aide des cadres cocos2d) c'est un projet qui est protégé par copyright par moi, alex Earley 2009.

Répondre

7

D'abord, [[effectsLayer alloc] retain] est terrible. Ne fais jamais cela. Déjà. N'utilisez jamais un objet alloué qui n'a pas été initialisé. En outre, cela conservera l'objet au moins deux fois, puisqu'un appel à + alloc renvoie un objet conservé, que vous le conservez à nouveau, puis en l'ajoutant à un tableau (qui le conserve une troisième fois), mais ce n'est que être publié deux fois (quand il est retiré du tableau et votre version singulière).

Je suppose que le problème est avec cette ligne: [self addChild:elayer z:2]; Que fait cette méthode? Est-ce qu'il est en charge de dessiner le calque sur l'écran? Si c'est le cas, alors cela signifie probablement qu'il conserve aussi elayer, ce qui signifie qu'il ne sera pas désalloué, car vous ne semblez pas faire d'appel "removeChild" quand vous faites sortir des objets de votre tableau mutable. En bref: juste parce que quelque chose ne se trouve plus dans votre tableau ne veut pas dire que ce n'est pas non plus à l'écran.

+1

Et même si 'addChild: z:' ne conserve pas l'objet mais garde une référence en quelque sorte, cela signifie simplement que vous avez encore la couche ajoutée en tant qu'enfant, mais elle va se bloquer un jour parce qu'elle a été 'dealloc' éd. – Chuck

+0

@Chuck +1 très vrai. –

+1

En outre, si vous ne le retenez pas dans 'addChild:' vous ne limiterez pas à 20 éléments, vous allez probablement tomber en panne. – bobDevil

Questions connexes