问题
I have been running Instruments to see why my SKScene won't deallocate and getting "leaks" that don't make any sense. One of the "leaks" is on a scene that properly deallocates and points to this:
border.path = path;
As the line causing the leak but the very next line is:
CGPathRelease(path);
border.lineWidth = 1.0f;
border.strokeColor = [SKColor yellowColor];
[border setAlpha:0.0f];
[border runAction:[SKAction fadeAlphaTo:1.0f duration:0.2f]];
[self addChild:border];
So you can clearly see it's released.I am also getting "leaks" for methods like:
-(void)explosionShake{
//[self testTargets];
NSArray *objectArray = [self children];
for (SKNode *node in objectArray) {
[node runAction:[SKAction moveBy:CGVectorMake(0.0f, 10.0f) duration:.05] completion:^{
[node runAction:[SKAction moveBy:CGVectorMake(0.0f, -15.0f) duration:.05] completion:^{
[node runAction:[SKAction moveBy:CGVectorMake(0.0f, 5.0f) duration:.05]];
}];
}];
}
}
After the scene ends, and also for another object which I remove from it's parent.
Could these "leaks" be caused by trying to run an action on a node that has been removed from it's parent? Because as "explosionshake" is running, one of the nodes may be removed from it's parent in another method. What about this method:
SKEmitterNode *testForExplosion = [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"explosionTest" ofType:@"sks"]];
//testForExplosion.position = location;
//[testForExplosion setParticleSpeed:self.frame.size.width/self.gameSpeed];
SKNode *node = [SKNode node];
[self addChild:node];
[node setPosition:location];
[node runAction:[SKAction moveBy:CGVectorMake(-self.frame.size.width, 0) duration:self.gameSpeed]];
[node addChild:testForExplosion];
SKAction *wait = [SKAction waitForDuration:4.0f];
SKAction *remove = [SKAction removeFromParent];
NSArray *array = [NSArray arrayWithObjects:wait,remove, nil];
SKAction *sequence = [SKAction sequence:array];
The first line in the method is highlighted in red and the last one in green (that's just a chunk of the method). I am pretty confused about why these are "leaks", but it's probably contributing to why my scene isn't getting deallocated.
If anybody could give me pointers as to why these methods could possibly be causing memory leaks, that would be very, very helpful. I have plenty more methods which are supposedly leaking SKCSprite
s, when my code clearly calls removeFromParent
回答1:
1) SKShapeNode
are not the most solid class to use in the game. I mean, better to use a SKSpriteNode
with a shape image. If still use SKShapeNode
, try code below. May not work, but give it a try.
- (void)dealloc
{
if(self.shapeNode){
[self.shapeNode setPath:NULL];
[self.shapeNode removeFromParent];
self.shapeNode = nil;
}
}
2)
It's clear that there is a strong reference to the node. May rewrite like:
-(void)explosionShake
{
NSArray *objectArray = [self children];
for (SKNode *node in objectArray) {
// create a weak reference of the node
__weak typeof(node) weaknode = node;
// run action
[node runAction:[SKAction moveBy:CGVectorMake(0.0f, 10.0f) duration:.05] completion:^{
[weaknode runAction:[SKAction moveBy:CGVectorMake(0.0f, -15.0f) duration:.05] completion:^{
[weaknode runAction:[SKAction moveBy:CGVectorMake(0.0f, 5.0f) duration:.05]];
}];
}];
}
}
3)
The third section seem to have some missing code because I don't see a leak.
Check this other thread for an example of how to run an action with a completion block.
SKAction Perform Selector syntax error
Hope this helps.
来源:https://stackoverflow.com/questions/27007350/sprite-kit-leaks-dont-make-sense