Я пытаюсь визуализировать текстуры в фоновом потоке в cocos2d, и все идет хорошо, за исключением того, что по какой-то причине я не могу выпустить текстуры, когда они больше не используются.
Сначала я загружаю два изображения асинхронно, затем я запускаю фоновую задачу, в которой я визуализирую новое изображение. Как я уже сказал, все работает нормально, проблема в том, что мое приложение вылетает после вызова этих функций несколько раз. Я понятия не имею, как сделать дополнительную очистку. Выход из моей доступной памяти говорит мне, что я каждый раз теряю от 10 до 15 МБ (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];
}