2
votes

I want to move a SKSpriteNode from one SKNode to another. The removeFromParent method actually deallocates the sprite.

For example in this code MySprite is a subclass of SKSpriteNode with a dealloc custom method that output a string, just to let me know that the object was deallocated:

SKNode *node1 = [SKNode node];
SKNode *node2 = [SKNode node];
//[self addChild:node1];
//[self addChild:node2];

MySprite *sprite = [MySprite spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(30, 30)];

[node1 addChild:sprite];
[sprite removeFromParent];
[node2 addChild:sprite];

In this case the sprite is deallocated. I thought that having a strong reference to sprite should keep it alive even after calling the removeFromParent, but it doesn't.

But if I uncommented [self addChild:node2]; The sprite was not deallocated.

I'm pretty confused here. If the removeFromParent deallocated the object, sprite should be nil and I should get an error for adding a nil node to parent. Isn't it? The documentation just say that removeFromParent: "Removes the receiving node from its parent." but it says nothing about how memory is managed here.

2

2 Answers

2
votes

removeFromParent: will not deallocate the node unless his parent was the only person who held reference to it(via parent->child relationship).

In your case if sprite was deallocated on removeFromParent you would see exception for adding nil child, as you suggested. Which leads to a conclusion it was not.

This gave me an idea what happened:

But if I uncommented [self addChild:node2]; The sprite was not deallocated.

You are probably checking for sprite outside of local scope.

{
    //Local scope starting
    SKNode *node = [SKNode node];
    //Node created and exists here

    //[self addChild:node];
    //Node is not added to scene or parent node(self)

    SKSPriteNode* sprite = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(30, 30)];
    [node addChild:sprite];
}
/*
Local scope ended if node isn't added to parent(self) it get deallocated, 
along with the content.
In case //[self addChild:node] was uncommented, node would not be deallocated
and sprite would still be "alive"
*/

As long as someone hold reference to a object it will not be deallocated.

4
votes

There is a method for this purpose:

 SKNode.moveToParent(parent: SKNode)

Moves the node to a new parent node in the scene. The node maintains its current position in scene coordinates.

Source: https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKNode_Ref/#//apple_ref/occ/instm/SKNode/moveToParent: