2013-05-28 70 views
0

我使用ARC進行內存管理。ARC內存分配與CCParticleSystemQuad

在遊戲開始之前,我使用了一個預加載場景,在該場景中我加載了大量將在我的遊戲中使用的CCParticleSystemQuad對象。所有在這部分進展順利,這裏是我的代碼:

// 
// ReadySteadyGo.m 

// 
// Created by Nik on 23/05/13. 
// Copyright 2013 __MyCompanyName__. All rights reserved. 
// 

#import "ReadySteadyGoLayer.h" 
#import "QuickStartLayer.h" 


@implementation ReadySteadyGoLayer 
// Helper class method that creates a Scene with the ReadySteadyLayer as the only child. 
+(CCScene *) scene{ 
    // 'scene' is an autorelease object. 
    CCScene *scene = [CCScene node]; 

    // 'layer' is an autorelease object. 
    ReadySteadyGoLayer *layer = [ReadySteadyGoLayer node]; 

    // add layer as a child to scene 
    [scene addChild: layer]; 

    // return the scene 
    return scene; 
} 
@synthesize particleExplosion; 


// on "init" you need to initialize your instance 
-(id) init 
{ 
    // always call "super" init 
    if((self=[super init])) { 

     compteur = 3; 
     plus10LablesArray = [[NSMutableArray alloc] initWithCapacity:400]; 
     whiteParticlesArray = [[NSMutableArray alloc] initWithCapacity:500]; 
     bombParticlesArray = [[NSMutableArray alloc] initWithCapacity:50]; 
     self.particleExplosion = [[CCParticleSystemQuad alloc] init]; 
     bombExplosion = [[CCParticleSystemQuad alloc] init]; 
     plus10Label = [[CCLabelTTF alloc] init]; 
     displayCompteur = [[CCLabelTTF alloc] init]; 
     self.particleExplosion = [CCParticleSystemQuad particleWithFile:@"whiteExplosion.plist"]; 
     bombExplosion = [CCParticleSystemQuad particleWithFile:@"explosion.plist"]; 
    } 

    [self schedule:@selector(initAll)]; 
    [self schedule:@selector(compt)]; 
    return self; 
} 

-(void)initAll{ 
    // Create a new NSOperationQueue instance. 
    operationQueue = [[NSOperationQueue alloc] init]; 
    // Create a new NSOperation object using the NSInvocationOperation subclass. 
    // Tell it to run the counterTask method. 
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self 
                      selector:@selector(initWhiteParticles) 
                       object:nil]; 
    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self 
                      selector:@selector(initBombParticles) 
                       object:nil]; 
    NSInvocationOperation *operation3 = [[NSInvocationOperation alloc] initWithTarget:self 
                      selector:@selector(initPlus10Labels) 
                       object:nil]; 
    // Add the operation to the queue and let it to be executed. 
    [operationQueue addOperation:operation1]; 
    [operationQueue addOperation:operation2]; 
    [operationQueue addOperation:operation3]; 
    [self unschedule:@selector(initAll)]; 

} 

- (void)compt{ 
    CGSize winSize = [CCDirector sharedDirector].winSize; 

    if (compteur == 3){ 
     displayCompteur = [CCLabelTTF labelWithString:[NSString stringWithFormat:@"%i...", compteur] fontName:@"Helvetica" fontSize:120]; 
     displayCompteur.position = ccp(winSize.width/2, winSize.height/2); 
     [self addChild:displayCompteur z:1000]; 
     compteur--; 
     [self unschedule:@selector(compt)]; 
     [self schedule:@selector(boucle) interval:1.0f]; 
    } 
    else if (compteur == 2){ 
     displayCompteur.string = [NSString stringWithFormat:@"%i..", compteur]; 
     compteur--; 
     [self schedule:@selector(compt) interval:1.0f]; 
    } 
    else if (compteur == 1){ 
     displayCompteur.string = [NSString stringWithFormat:@"%i.", compteur]; 
     compteur--; 
     [self schedule:@selector(compt) interval:1.0f]; 
    } 
    else if (compteur == 0){ 
     displayCompteur.string = @"GO"; 
     displayCompteur.fontSize = 25; 
     compteur--; 
     [self schedule:@selector(compt) interval:1.0f]; 
    } 
    else{ 
     [self unschedule:@selector(compt)]; 
     [[CCDirector sharedDirector] pushScene:[QuickStartLayer scene:plus10LablesArray:whiteParticlesArray: bombParticlesArray]]; 
    } 

}

- (void)initWhiteParticles{ 
    int index = 0; 
    for (index = 0; index < 500; index++) { 
     self.particleExplosion = [CCParticleSystemQuad particleWithFile:@"whiteExplosion.plist"]; 
     [whiteParticlesArray performSelectorOnMainThread:@selector(addObject:) withObject:self.particleExplosion waitUntilDone:NO]; 
    } 
} 

- (void)initBombParticles{ 
    int index = 0; 
    for (index = 0; index < 50; index++) { 
     bombExplosion = [CCParticleSystemQuad particleWithFile:@"explosion.plist"]; 
     [bombParticlesArray performSelectorOnMainThread:@selector(addObject:) withObject:bombExplosion waitUntilDone:NO]; 
    } 
} 

- (void)initPlus10Labels{ 
    int index = 0; 
    for (index = 0; index < 400; index++) { 
     plus10Label = [CCLabelTTF labelWithString:@"+10" fontName:@"Helvetica" fontSize:20]; 
     [plus10LablesArray performSelectorOnMainThread:@selector(addObject:) withObject:plus10Label waitUntilDone:NO]; 
    } 
} 

@end 

的問題是,當我在儀器(分配)檢查,我可以看到[CCParticleSystemQuad分配存儲器]增加每個時間。用我的比賽15分鐘後,它崩潰...

當我在我的顆粒的使用我這樣做:

explosion = [_whiteParticlesArray objectAtIndex:nextWhiteParticle]; 
nextWhiteParticle++; 
explosion.position = ccp(posX, posY); 
[particleToDelete addObject:explosion]; 
[self addChild: explosion]; 

我創建了一個函數來清理這是粒子:

- (void)cleanParticles{ 
    for (int i = 0; i < [particleToDelete count]; i++) { 
     id object = [particleToDelete objectAtIndex:i]; 
     [particleToDelete removeObject:object]; 
     [self removeChild:object cleanup:YES]; 
    } 
} 

在這裏的比賽結束是我做的:

[self unschedule:@selector(countDown:)]; 
[self unschedule:@selector(addAllSprites:)] 
[self unschedule:@selector(displayScore:)]; 
[self unschedule:@selector(cleanParticles)]; 
[self unschedule:@selector(cleanLabels)]; 
[_whiteParticlesArray removeAllObjects]; 
[_bombParticlesArray removeAllObjects]; 
[_plus10LabelsArray removeAllObjects]; 
[self removeChild:_spriteSheet cleanup:YES]; 

所以我刪除了所有對象,ARC應該CL能夠記住那些對象嗎?問題是它沒有。

謝謝你的幫助球員:)。

編輯1

我真的卡住了...我刪除了我的所有對象這是在我的NSMutableArray但ARC不釋放他們。有人尋求幫助?

Thx

回答

0

那一個看起來很明顯。你有所有的粒子存儲在_whiteParticlesArray,對不對?所以只要粒子仍在該陣列中,它們將被陣列保留並保留在內存中。

當您刪除所有對象時,儀器中的內存使用情況不會發生變化(顯着),您可能還有其他泄漏。你應該檢查儀器的一件事是有多少顆粒物體存在。並且確保在更改場景後驗證場景實例本身已被釋放。

順便提一下,創建數百個粒子系統並不是非常有效。在需要時創建粒子時,您是否遇到性能問題?如果沒有,請立即創建它們。請記住,每個粒子系統本身都使用大約500個字節,因此500個粒子系統對於類實例大約爲250 KB。

您仍然可以預加載紋理,這是最重要的部分。您只需創建使用嵌入紋理的每種粒子類型之一,或使用紋理高速緩存預先加載沒有嵌入紋理的粒子系統plists的紋理。

+0

我檢查了儀器,我沒有泄漏......好吧,我會檢查有多少顆粒物體存活。你在說哪個場景?我的預載場景或我的遊戲場景?是的,我有性能問題,因爲在我的遊戲中,一旦用戶觸摸屏幕,就會產生粒子效應。如果你多次觸摸屏幕,FPS下降(大約25 FPS),現在它在(55-60)左右。我試圖使用一個粒子系統管理器,但我有一個問題,與我的addChild。事實上,我無法添加相同的CCParticleSystemQuad。我不知道如何去做你最後的建議。很多,我很欣賞。 – Niknolty