Hi,
I'm on my second app, now with 2.0. I'm running into a situation where, in Instruments, the Dirty memory grows and grows, even though I remove and deallocate scenes, as well as release the textures associated. For some reason, the memory leaks.
I'm using a modified version of the Media class, which preloads SPTextureAtlas objects in the background, like so:
+ (void) preloadTexturesForKey:(NSString *)key onComplete:(PreloadBlock)callback
{
@synchronized(textures)
{
if ([textures objectForKey:key]) // means texture is loaded in memory, so skip it
{
return;
}
}
[SPTexture loadFromFile:[NSString stringWithFormat:@"%@_atlas.png", key] onComplete:^(SPTexture *texture, NSError *outError)
{
NSString* file = [key stringByAppendingString:@"_atlas.xml"];
SPTextureAtlas *atlas = [[SPTextureAtlas alloc] initWithContentsOfFile:file texture:texture];
@synchronized(textures)
{
[textures setObject:atlas forKey:key];
NSLog(@"Textures loaded: %@ and %@", file, key);
callback([NSString stringWithFormat:@"%@", key]);
}
}];
}
This method will load textures and create references, given a key, in an NSDictionary. Always worked fine. This is how I release the textures when scenes are removed:
+ (void) releaseTexturesForKey:(NSString *)key
{
NSMutableArray *remove = [[NSMutableArray alloc] init];
@synchronized(textures)
{
for (NSString *k in textures) {
if ([k isEqualToString:key]) {
NSLog(@"Releasing %@", k);
[remove addObject:k];
}
}
[textures removeObjectsForKeys:remove];
}
}
During debug, I can confirm that the objects are actually removed from the "textures" dictionary. It only keeps the textures that I currently need at any given point of the app.
My scenes are all loaded in an SPSprite that I extended, and this sprite is the only direct child of the SPStage.
This is how I remove the scenes:
- (void) forward
{
[_currentScene stop:^(NSString *message) {
[_currentScene removeAllChildren];
[_currentScene removeFromParent];
_currentScene = nil;
[self nextScene];
}];
}
Could it be a bug or should I do something else?
- Remove any listeners?
- Check for delegates, blocks? The call to load the next scene is from a block that executes after its invoked from the current scene.
- Do I still need to maybe add the SPStage to an @autoreleasepool {...} block?
This issue is a lot like this one I found, but it didn't hit home run to me:
http://forum.sparrow-framework.org/topic/correct-scene-management-in-sparrow-2#post-18165
Cheers,
Henrique