Cocos2d not releasing memory - memory

I have a Cocos2d game that contains a loading between 3 'worlds'. To do this the app uses:
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:spriteSheetName];
To unload the previous 'world' in the loading I do:
[[CCSpriteFrameCache sharedSpriteFrameCache]removeSpriteFramesFromFile:plist];
NSString * textureFileName = [plist stringByDeletingPathExtension];
CCTexture2D *texture = [[CCTextureCache sharedTextureCache] textureForKey:[textureFileName stringByAppendingPathExtension:#"pvr.ccz"]];
[[CCTextureCache sharedTextureCache] removeTexture:texture];
When using dumpCachedTextureInfo I receive:
CCTextureCache dumpDebugInfo: 36 textures, for 190476 KB (186.01 MB)
However Xcode memory tab shows around 600MB. I'm using an iPad 3 for testing. Finally after some memory warnings Xcode shows: 'Terminated due to Memory Pressure'.
Do anyone know why I have different memory values?

Make sure you are also releasing your touch delegate when you change scenes.

Related

Preload Images in cocos2d v3

I'm trying to preload the images that I'm using before the game starts.
But, I looking around, I just find this line which is wrote in cocos2d v2.
[[CCTextureCache sharedTextureCache ] addImage:#"objects.png" ];
How can I preload the images in cocos2d v3?
In cocos2d-v3, instead of using CCTextureCache, you can use simply CCTexture’s (previously CCTexture2D) textureWithFile: initializer.
Your code would look like:
CCTexture* texture = [CCTexture textureWithFile:#"objects.png"];
If I understand the docs correctly, it will cache the texture file (see CCTexture extureWithFile:).
So, if you already have loaded the texture before, it will be in cache, and the previously created texture will be returned by the code above.
There is another "work-around" solution also here: https://gamedev.stackexchange.com/questions/72713/preload-in-cocos2d-v3
Actually CCTextureCache is still there in Cocos2D version 3.x. But it is not directly accessible if you just import "cocos2d.h". To access it you have to import "CCTextureCache.h".
Try this code:
#import "CCTextureCache.h"
- (void) preloadImages
{
[[CCTextureCache sharedTextureCache] addImage:#"image1.png"];
[[CCTextureCache sharedTextureCache] addImage:#"image2.png"];
[[CCTextureCache sharedTextureCache] addImage:#"image3.png"];
[[CCTextureCache sharedTextureCache] addImage:#"image4.png"];
[[CCTextureCache sharedTextureCache] addImage:#"image5.png"];
}
Try this:
cocos2d::Director::getInstance()->getTextureCache()->addImage("objects.png");

Replace scene goes on increasing memory usage and memory leak too how to handle that? or How should I enable ARC in my project

I am working on a cocos2d project which is a game with many scenes.
When I call replace scene ,I use
[scene2 removeAllChildrenWithCleanup:YES];
In the dealloc method.
Also, I have removed all the unused spritesheets by using
NSString *PngName = [atlas.AtlasName stringByAppendingString:#".png"];
NSString *PlistName = [atlas.AtlasName stringByAppendingString:#".plist"];
[[CCSpriteFrameCache sharedSpriteFrameCache] removeSpriteFramesFromFile:PlistName];
[[CCSpriteFrameCache sharedSpriteFrameCache] removeSpriteFrameByName:PngName];
[[CCSpriteFrameCache sharedSpriteFrameCache] removeSpriteFrames];
When I check the description of my
[CCSpriteFrameCache sharedSpriteFrameCache]
, It shows me that it removes the unused spritesheets but it does not free the memory when I check on device with Instrumets. This results in app crash.
After many trials I thought of using ARC in my project but when I convert it to ARC project even after following steps shown in
http://www.youtube.com/watch?v=Klj9xRafog4
I get many errors in my CCArray, CCDirectorIOS etc..
Can anybody help me to solve this issue??
Check that you are removing your touch delegate when you are changing scenes.
Try using purgeSharedSpriteFrameCache of CCSpriteFrameCache and removeUnusedSpriteFrames and removeUnusedTextures. Have a look at these threads for more details:
Release all texture memory
Correct way to remove sprite cache
Hope it helps!

Clearing elements from a CCBI file from CCTextureCache and CCSpriteFrameCache

Currently i'm making a game using cocos2d and i've come up on a situation that i'm having trouble dealing with. The game has a loading screen that uses a CCB file and is read in using CCBReader and this causes it to be added to the caches. After the user exits the loading screen and enters the game i would like to clear the textures that the loading screen uses from the cache. I know you can use something like
[[CCSpriteFrameCache sharedSpriteFrameCache] removeSpriteFrameByName:item];
[[CCTextureCache sharedTextureCache] removeTextureForKey:item];
but this doesn't clear it from the texture when loaded from a CCB file. Any body have this situation before or knows how to deal with it?
Instantiate and use a CCSpriteFrameCache and CCTextureCache for your own assets. Then clear the shared caches completely:
[[CCSpriteFrameCache sharedSpriteFrameCache] removeSpriteFrames];
[[CCTextureCache sharedTextureCache] removeAllTextures];

Preloading Sprite Sheets with cocos2d

I have a game which has many unique units, and each unit has its own sprite sheet (because each unit has several animations), meaning there may be upwards of a dozen sprite sheets used by the game on any given scene. When the scene with the units is created, the initialization of all these assets takes a lot of time (a couple seconds). Specifically, the UI is locked while this code is run:
NSString *unitSheetName = [self getUnitSheetName];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:unitSheetName];
CCSprite *frame = [CCSprite spriteWithSpriteFrameName:kDefaultFrameName];
// etc...
However, if I then pop the scene, and then create a new version of the same scene (and push it), the loading takes a fraction of the time (the UI does not lock). Thus, it seems the UI locking is due to the initial caching of the sprite sheets...
My hope was that I'd be able to avoid this lag by calling the CCSpriteFrameCache's addSpriteFramesWithFile method while the game is starting up, but this does not seem to work. Despite doing this, the initial load still takes a long time.
Is there any good, effective way to preload the assets? I don't mind adding a second or two to my startup loading screen, if only I can be sure that the UI will later not be locked when the scene is pushed...
Per #LearnCocos2D's reply, above, here's how to properly and fully pre-load a sprite sheet, (fpSheet is the file path of the sheet):
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:fpSheet];
NSDictionary *spriteSheet = [NSDictionary dictionaryWithContentsOfFile:fpSheet];
NSString *fnTexture = spriteSheet[#"metadata"][#"textureFileName"];
[[CCTextureCache sharedTextureCache] addImage:fnTexture];

Cocos2d: particle.autoRemoveOnFinish not releasing memory

I create a particle effect in the following way:
CCParticleSun* p = [[CCParticleSun alloc]initWithTotalParticles:5000];
p.autoRemoveOnFinish = YES;
//more parameters
p.duration = 1;
and add it to my scene:
[self addChild:p z:self.zOrder+1];
Every time I create this particle effect, 3MB of memory are allocated, but never released.
What am I doing wrong? Do I have to manually release the particle system?
NSZombies are disabled, so it's not kept in memory by accident.
Everything you alloc (or retain) you have to release as well. For Cocos2D it's easiest to turn it into an autorelease object like this:
CCParticleSun* p = [[CCParticleSun alloc]initWithTotalParticles:5000];
[p autorelease];
p.autoRemoveOnFinish = YES;
p.duration = 1;
Then it will be released after Cocos2D cleans up your scene.
PS: 5000 particles is a GIGANTIC amount of particles! No wonder you're seeing allocations of several megabytes in size. Try going for 500 at most,
100 or less if you're using particle textures that are about 32x32 pixels or greater.

Resources