Memory Leak in Sprite Kit Application

2019-05-13 19:09发布

问题:

I have a Sprite Kit game that I created in Xcode 5 and when profiling it for leaks using Instruments I see that there are indeed some leaks:

The problem is that I can't tell where in my application this is coming from as the "Responsible Frame" column doesn't point me to anywhere in my application.

How would one go about debugging/tracking the origins of this issue?

Update #1

There is only one file in which I'm interacting w/ CGPath but I am calling CGPathRelease

...
CGMutablePathRef path = CGPathCreateMutable();

CGPathMoveToPoint(path, NULL, 0, 0);
CGPathAddLineToPoint(path, NULL, size.width, 0);
CGPathAddLineToPoint(path, NULL, size.width, (upperCount * size.width));
CGPathAddLineToPoint(path, NULL, 0, (upperCount * size.width));

CGPathCloseSubpath(path);

upper.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];

CGPathRelease(path);
...        

Update #2

After toggling open the right panel in Instruments I was able to see the offending lines (although I'm still not sure is wrong here):

The first set of leaks...

The second set of leaks...

回答1:

Have you seen this? SKPhysicsBody bodyWithPolygonFromPath memory leaks

Looks like its a spritekit bug in SKPhysicsBody (I would guess it is being retained within bodyWithPolygonFromPath but not released).



回答2:

Hmm... I'm really not sure what is going on here. However, would it be possible to try it using UIBezierPath to create the path instead.

Just to test it...

CGMutablePathRef path = CGPathCreateMutable();

CGPathMoveToPoint(path, NULL, 0, 0);
CGPathAddLineToPoint(path, NULL, size.width, 0);
CGPathAddLineToPoint(path, NULL, size.width, (upperCount * size.width));
CGPathAddLineToPoint(path, NULL, 0, (upperCount * size.width));

CGPathCloseSubpath(path);

upper.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];

CGPathRelease(path);

Would become...

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, 0)];
[path addLineToPoint:CGPointMake(size.width, 0)];
[path addLineToPoint:CGPointMake(size.width, (upperCount * size.width))];
[path addLineToPoint:CGPointMake(0, (upperCount * size.width))];
[path closePath];

upper.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path.CGPath];

Just to see if that stops the leaks. If so... keep it :D

If you have to use the path multiple times then you can keep a reference to it so you can lazily load it and then only have to load it once.