如何正确地释放一组继承自 SKSpriteNode 的对象

How to properly deallocate a Set of objects that inherit from SKSpriteNode

我想知道解除分配从 SKSpriteNode 继承的 Set 对象的最佳方法是什么。我有以下代码:

class Raindrop : SKSpriteNode
{    
weak var barSpriteRef: SKSpriteNode?

init(scene: SKScene, barSprite: SKSpriteNode)
{
    let texture = SKTexture(imageNamed: "RainDrop")

    super.init(texture: texture, color: SKColor.whiteColor(), size: texture.size())

    barSpriteRef = barSprite

    self.userInteractionEnabled = true

    let width = scene.view!.frame.width

    let randomPos = CGPointMake(CGFloat(arc4random()) % width, UIScreen.mainScreen().bounds.height + 50)

    self.position = randomPos
    self.zPosition = 1
    self.anchorPoint = CGPoint(x: 0.5, y: 0.5)

    scene.addChild(self)

    let moveDown = SKAction.moveToY(-UIScreen.mainScreen().bounds.height, duration: 8)
    self.runAction(moveDown)
}

required init?(coder aDecoder: NSCoder)
{
    fatalError("init(coder:) has not been implemented")
}

func kill()
{
    self.removeAllActions()
    self.removeFromParent()
}
}

函数 kill() 是我尝试解除分配的尝试,但它没有按预期工作。

我正在使用这样的集合:

var raindrops = Set<Raindrop>()

ARC 的工作原理

ARC 会在内存中保留被强引用的对象。

SpriteKit

这在 SpriteKit 中也是如此,事实上每个被 GameScene 强烈引用的节点(或被 GameScene... 引用的节点引用)都保存在内存中。

你做的是正确的(但可能还不够)

您正在尝试使用您的 kill 方法解除分配您的 Raindrop 精灵

func kill() {
    self.removeAllActions()
    self.removeFromParent()
}

此方法有效如果 当前 Raindrop 仅由其父级和某些操作引用。

但是,如果您在另一个节点中创建了这个 Set

var raindrops = Set<Raindrop>()

然后将您的 sprite 添加到 Set,您创建了另一个 strong reference,它将在内存中保留您的 Raindrop sprite。

例子

让我们定义一个 GameScene 和一个 Hero 节点。

class GameScene: SKScene {
    deinit { print("GameScene has been deallocated") }
}

class Hero: SKNode {
    deinit { print("Hero has been deallocated") }
}

The deinit will print a message into the console as soon as the object is deallocated

现在让我们看一下这段代码

let scene = GameScene(size: CGSize(width: 100, height: 100))
var hero: SKNode? = Hero()
var set = Set<SKNode>([hero!])
scene.addChild(Hero())

Hero 对象有 3 个强引用

  1. 来自 scene
  2. hero变量
  3. set变量

让我们删除前 2 个引用

hero?.removeFromParent()
hero = nil

英雄仍然在记忆中,因为 set.

强烈引用

最后让我们运行

set.removeAll()

现在我们收到以下消息,因为 Hero 终于被释放了。

Hero has been deallocated