Why do creating and deleting SKShapeNode and SKNode repeatedly cause a memory leak?

Using the sprite set template that comes with Xcode, I modify the scene 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 

It seems that the application is using more memory until it freezes or crashes (after reaching about 180 MB). Using leakage and distribution tools, I found the following:

A leak: Screenshot of Leaks window Deductions: Screenshot of Allocations window

As you can see 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. Similarly, there are a number of memory leaks that are also apparently associated with SKShapeNode, SKNode, or other Sprite Kit objects.

How to get around or solve this memory problem (leak)? I need to create SKShapeNodes and SKNodes for each frame. This code is just a model to illustrate the problem - my actual project is much more complex with dynamically generated paths (not static, as in this example).

+6
source share
4 answers

This is a bug in the sprite set. The problem is not only in SKShapeNode, but also in SKPhysicsBody.

Creating a physical body or form using CGPath causes a memory leak. You can verify this by commenting on the physical body or form and working devices with leaks, secretions, and a memory monitor.

Even if you let go the right way, the set of sprites will not be internally. You can't do anything!

Launch the tools and watch the memory grow! Xd

EDIT: This error was present in iOS 7.0. Whether this was fixed in 7.1 or later is not known to me because I stopped using SpriteKit due to this error. You can check if this is fixed by simple testing.

+12
source

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 it is 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. For instance:

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

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

+2
source

I am using iOS 7.1.1 and have the same problem. However, by setting the SKShapeNode path property to nil before you remove the shape from the parent, fix this problem - no more leaks.

+2
source

I have the same problem.

The scene added one node connection (SKShape with SKSprite), after which I removed this node from the scene and added again (I had leaks on two nodes).

My leak is recorded by the recreational node node after being removed from the scene

0
source

Source: https://habr.com/ru/post/959064/


All Articles