SKShapeNode has unlimited memory growth

If I run this code in the init sublass method for SKScene

for (int i = 0; i < 100; i++) { SKShapeNode *shape = [SKShapeNode node]; shape.antialiased = NO; CGMutablePathRef path = CGPathCreateMutable(); CGPathAddEllipseInRect(path, NULL, CGRectMake(arc4random()%320, arc4random()%320, 10, 10)); shape.path = path; [shape setStrokeColor:[UIColor blackColor]]; CGPathRelease(path); [self addChild:shape]; [shape removeFromParent]; } 

and every time I run this code in the SKView control controller

 SKView * skView = (SKView *)self.view; // Create and configure the scene. SKScene * scene = [ZTMyScene sceneWithSize:skView.bounds.size]; scene.scaleMode = SKSceneScaleModeAspectFill; // Present the scene. [skView presentScene:scene]; 

my memory usage grows until the memory is full and fails. This does not happen if I use SKSpriteNode. Anyone fix this?

Summary: I am creating a sprite set template project, add a lot of SKShapeNodes and replace the old SKScene with a new one.

I added a sample project to github https://github.com/zeiteisen/MemoryTest

+6
memory-management ios7 sprite-kit
source share
2 answers

I became aware of this problem by reading another entry. I messed up a bit of SKShapeNode and really checked for the memory leak problem mentioned here.

I had an idea ...

Not a completely new idea, more revised. This great idea actually allowed me to use SKShapeNodes for my heart :)

pooling

Yes ... I just created the SKShapeNodes pool, which I reused as needed. Who cares what it does :)

You simply redefine the path when necessary, when done by returning to your pool, and it will wait for you to play with it again later.

Create an ivar or NSMutableArray property in your SKScene name SKScene and create it when you start SKScene . You can either populate the array with your form nodes during init, or create them as needed.

This is the quick method I created to grab a new node from the pool:

 -(SKShapeNode *)getShapeNode { if (pool.count > 0) { SKShapeNode *shape = pool[0]; [pool removeObject:shape]; return shape; } // if there is not any nodes left in the pool, create a new one to return SKShapeNode *shape = [SKShapeNode node]; return shape; } 

So, wherever you are in the scene, you need an SKShapeNode that you would do:

 SKShapeNode *shape = [self getShapeNode]; // do whatever you need to do with the instance 

When you finish using the node form, just return it to the pool and set the path to NULL, for example:

 [pool addObject:shape]; [shape removeFromParent]; shape.path = NULL; 

I know this is a workaround, not an ideal solution, but certainly it is a very viable workaround for those who want to use a large number of SKShapeNodes and not flush the memory.

+1
source share

You add the form and immediately after it is deleted, why?

 [self addChild:shape]; [shape removeFromParent] 
0
source share

All Articles