Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does creating and removing SKShapeNode and SKNode repeatedly cause a memory leak?

Using the sprite kit template that comes with Xcode, I modify the scene to be as follows :

#import "MyScene.h"

@interface MyScene ()
@property (nonatomic,strong)SKNode *floor;
@end

@implementation MyScene

-(id)initWithSize:(CGSize)size {    
    if (self = [super initWithSize:size]) {
        /* Setup your scene here */
    }
    return self;
}

-(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */
    [self removeAllChildren];
    self.floor = nil;
    self.floor = [SKNode node];

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, nil, 0, 10);

    for(int i = 2; i<self.frame.size.width; i+=2)
    {
        CGPathAddLineToPoint(path, nil, i, 10);
    }

    self.floor.physicsBody = [SKPhysicsBody bodyWithEdgeChainFromPath:path];
    SKShapeNode *shape = [SKShapeNode node];
    shape.path = path;
    shape.strokeColor = [UIColor redColor];

    [self.floor addChild:shape];
    [self addChild:self.floor];

    CGPathRelease(path); 
}

@end

The app seems to keep using more memory, until it either hangs or crashes (after reaching about 180MB). Using the leaks and allocations tools, I have found the following:

Leaks: Screenshot of Leaks window Allocations: Screenshot of Allocations window

As can be seen from the images, there are a large number of Malloc calls using memory. I do not call Malloc directly - it seems these calls are made by SpriteKit. Likewise, there are a number of memory leaks, which also seem to be due to SKShapeNode, SKNode or other Sprite Kit objects.

How do I work around or solve this memory(leak) problem? I have to create SKShapeNodes, and SKNodes every frame. This code is just a sample to illustrate the problem - my actual project is much more complex with dynamically generated paths (not static like the one in this example).

like image 864
Rahul Iyer Avatar asked Nov 29 '13 19:11

Rahul Iyer


1 Answers

This is a bug in sprite kit. The problem isn't just with SKShapeNode, it is also with SKPhysicsBody.

Creating either a physics body, or a shape, using a CGPath causes a memory leak. You can verify this by commenting out either the physics body, or the shape, and running instruments with leaks, allocations and memory monitor.

Even if you release the path properly, sprite kit doesn't internally. Nothing you can do!

Fire up instruments, and watch the memory grow! XD

EDIT: This bug was present in iOS 7.0. Whether it has been fixed in 7.1 or later is not known to me as I stopped using SpriteKit because of this bug. One can verify if it is fixed by simply testing it.

like image 51
Rahul Iyer Avatar answered Sep 29 '22 13:09

Rahul Iyer