如何在SKNodes之间移动SKSpriteNode

时间:2014-02-07 21:24:50

标签: ios7 automatic-ref-counting sprite-kit skspritenode sknode

我想将SKSpriteNode从一个SKNode移动到另一个SKNode。 removeFromParent方法实际上释放了sprite。

例如在这段代码中,MySprite是SKSpriteNode的子类,带有dealloc自定义方法,输出一个字符串,只是为了让我知道该对象已被释放:

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];

在这种情况下,精灵被解除分配。我认为有一个强大的精灵参考应该在调用removeFromParent后保持活着,但事实并非如此。

但如果我取消注释[self addChild:node2];精灵没有被解除分配。

我在这里很困惑。如果removeFromParent释放了对象,则sprite应为nil,并且我应该在向父级添加nil节点时出错。不是吗?文档只是说removeFromParent:“从其父节点中删除接收节点。”但它没有说明如何管理内存。

2 个答案:

答案 0 :(得分:4)

有一种方法可以达到这个目的:

 SKNode.moveToParent(parent: SKNode)

将节点移动到场景中的新父节点。节点在场景坐标中保持其当前位置。

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

答案 1 :(得分:2)

removeFromParent:不会释放该节点,除非他的父母是唯一一个引用它的人(通过parent->子关系)。

在你的情况下,如果在removeFromParent上释放了sprite,你会看到添加nil child的异常,如你所建议的那样。这导致了结论,但事实并非如此。

这让我知道发生了什么:

  

但如果我取消注释[self addChild:node2];精灵没有被解除分配。

您可能正在检查本地范围之外的精灵。

{
    //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"
*/

只要有人持有对象的引用,它就不会被释放。