Search code examples
ios7automatic-ref-countingsprite-kitskspritenodesknode

How to move SKSpriteNode between SKNodes


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.


Solution

  • 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.