我想将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:“从其父节点中删除接收节点。”但它没有说明如何管理内存。
答案 0 :(得分:4)
有一种方法可以达到这个目的:
SKNode.moveToParent(parent: SKNode)
将节点移动到场景中的新父节点。节点在场景坐标中保持其当前位置。
答案 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"
*/
只要有人持有对象的引用,它就不会被释放。