CCRenderTexture消耗了我的记忆

时间:2012-05-06 17:58:27

标签: ios memory cocos2d-iphone textures

我尝试在cocos2d中的后台线程中渲染纹理并且进展顺利,除了由于某种原因我不能在不再使用时释放纹理。

首先加载两个图像异步,然后我运行一个后台任务,在那里我渲染一个新图像。正如我所说它工作正常,问题是我的应用程序崩溃后调用这些功能几次。我不知道如何做更多的清理工作。注销我的可用内存告诉我每次丢失10-15 mb(gfx1和gfx2是视网膜全屏背景)。

问题必须在这些代码行中,因为当我删除它们时,我不再有内存问题,并且我的应用程序分析说没有泄漏!

纹理是NSMutableArray。我在索引0处有一个纹理,渲染一个新的并在位置1处添加它。在替换精灵后,我尝试在索引0处杀死我的(现在旧的)纹理,并且我的新纹理变为索引0,所以我可以运行这个功能一遍又一遍。

所以这是代码

- (void) startBuildingTextureInBackground {
    [[CCTextureCache sharedTextureCache] addImageAsync:@"gfx1.png"
                                                target:self
                                              selector:@selector(imageLoaded:)];
}

- (void) imageLoaded: (id) obj {
    rtxTexture1 = [[CCTextureCache sharedTextureCache] textureForKey:@"gfx1.png"];
    [[CCTextureCache sharedTextureCache] addImageAsync:@"gfx2.png"
                                                target:self
                                              selector:@selector(imageLoaded2:)];
}

- (void) imageLoaded2: (id) obj {
    rtxTexture2 = [[CCTextureCache sharedTextureCache] textureForKey:@"gfx2.png"];
    [self performSelectorInBackground:@selector(buildRtxTexture) withObject:nil];
}

- (void) buildRtxTexture {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    EAGLSharegroup *sharegroup = [[[[CCDirector sharedDirector] openGLView] context] sharegroup];
    EAGLContext *k_context = [[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 sharegroup:sharegroup] autorelease];
    [EAGLContext setCurrentContext:k_context];
    [[CCDirector sharedDirector] setGLDefaultValues];

    CCSprite* gfx1 = [CCSprite spriteWithTexture:rtxTexture1];
    [rendernode addChild:gfx1];

    CCSprite* gfx2 = [CCSprite spriteWithTexture:rtxTexture2];
    [rendernode addChild:gfx2];

    CCRenderTexture* rtx = [CCRenderTexture renderTextureWithWidth:512
                                                            height:320
                                                       pixelFormat:kTexture2DPixelFormat_RGBA4444];

    [rtx beginWithClear:0 g:0 b:0 a:0];
    [rendernode visit];

    [rtx end];

    [rendernode removeChild:gfx1 cleanup:YES];
    [rendernode removeChild:gfx2 cleanup:YES]; 

    [[CCTextureCache sharedTextureCache] removeTexture:rtxTexture1];
    [[CCTextureCache sharedTextureCache] removeTexture:rtxTexture2];

    [EAGLContext setCurrentContext:nil];
    [self performSelectorOnMainThread:@selector(textureLoaded:) withObject:rtx.sprite.texture waitUntilDone:YES]; 

    [pool release];
}

- (void) textureLoaded:(CCTexture2D*) newTexture {
    [textures addObject:newTexture];
}

- (void) replaceTexture {
    if (rtxSprite != nil) {
        [spriteDisplay removeChild:rtxSprite cleanup:YES];
        [[CCTextureCache sharedTextureCache] removeTexture:[textures objectAtIndex:0]];
        [textures removeObjectAtIndex:0];
    }

    rtxSprite = [CCSprite spriteWithTexture:[textures objectAtIndex:0]];
    rtxSprite.scaleY = -1;
    [spriteDisplay addChild: rtxSprite];
}

2 个答案:

答案 0 :(得分:0)

  1. 尝试调试代码:添加断点或NSLog / CCLOG来跟踪CCTexture2D / CCRenderTexture init / dealloc方法的调用。

  2. 您在后台线程中存在CCRenderTexture的潜在问题。当我尝试使用CCRenderTexture来处理纹理时,结果是意外的(黑色纹理或崩溃)。这是因为在主循环中调用OpenGL函数也是OpenGL是状态机。解决方法是在主线程中调用CCRenderTexture方法(performSelectorOnMainThread)。

答案 1 :(得分:0)

在将上下文设置为nil之前调用[pool release]可以解决问题。