【问题标题】:How to properly deallocate a Set of objects that inherit from SKSpriteNode如何正确释放一组继承自 SKSpriteNode 的对象
【发布时间】:2016-07-13 16:30:22
【问题描述】:

我想知道释放从 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 会在没有引用对象时为您执行此操作。当您没有说出它在做什么或预期的行为是什么时,说“它没有按预期工作”是一个无用的陈述。
  • 你永远不会从集合中移除雨滴,所以它不会释放。 parent 仅适用于SKNodes,不适用于Sets

标签: ios swift sprite-kit automatic-ref-counting


【解决方案1】:

ARC 的工作原理

ARC 确实将被强引用的对象保存在内存中。

SpriteKit

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

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

您正在尝试使用您的 kill 方法释放您的 Raindrop 精灵

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

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

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

var raindrops = Set<Raindrop>()

然后将您的精灵添加到Set,您创建了另一个强引用,它将您的Raindrop 精灵保留在内存中。

示例

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

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

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

deinit 将在对象被释放后立即在控制台中打印一条消息

现在让我们看看这段代码

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

【讨论】:

  • 不要忘记闭包,可能会发生循环引用,不允许引用对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多