2

我想将 SKSpriteNode 从一个 SKNode 移动到另一个。removeFromParent 方法实际上解除了精灵的分配。

例如,在这段代码中,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 之后,对 sprite 的强引用也应该使其保持活动状态,但事实并非如此。

但是如果我取消注释 [self addChild:node2]; 精灵没有被释放。

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

4

2 回答 2

4

为此目的有一种方法:

 SKNode.moveToParent(parent: SKNode)

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

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

于 2016-06-22T23:48:07.527 回答
2

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

在您的情况下,如果 sprite 在 removeFromParent 上被释放,您会看到添加 nil 孩子的异常,正如您所建议的那样。这导致了一个结论,它不是。

这让我知道发生了什么:

但是如果我取消注释 [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"
*/

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

于 2014-02-07T22:17:48.007 回答