如何从内存中清除SKSpriteNodes?

时间:2016-10-28 19:36:01

标签: swift memory sprite-kit skspritenode

我通过调用一个创建SKSpriteNode子类实例的函数,从gameScene和其他对象中创建了一堆sprite。

例如,来自GameScene,就像这样:

let sizee = CGSize(width: 100, height: 100)
let posi = CGPoint(x: 200, y: 300)

func createSprite(){
    let new = Circle(color: SKColor.blue, size: sizee , position: posi)
    addChild(new)
    new.zPosition = 2
}

从Circle内部,我在完成一些动画后删除每个实例:

import SpriteKit

class Circle: SKSpriteNode {

    let fade = SKAction.fadeAlpha(to: 0.5, duration: 2)
    let myScale = SKAction.scaleX(to: 3, duration: 2)
    let die = SKAction.removeFromParent()

    override init(texture: SKTexture?, color: UIColor, size: CGSize) {
        super.init(texture: texture, color: color, size: size)
    }
    convenience init(color: UIColor, size: CGSize, position: CGPoint) {
        self.init(color: color, size: size)
        self.position = position
        self.run(SKAction.sequence([fade, die]))
        self.run(myScale)
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

这足以确保它们从内存中释放出来吗?

或者我是否还需要做些其他事情来将它们从游戏世界和记忆中冲洗出来?

3 个答案:

答案 0 :(得分:5)

几周前,Apple已更新此page

  

Swift使用自动引用计数(ARC)来跟踪和管理您的   应用程序的内存使用情况。在大多数情况下,这意味着内存管理   在Swift中“只是工作”,你不需要考虑记忆   管理自己。 ARC自动释放使用的内存   不再需要这些实例的类实例。

     

引用计数仅适用于类的实例。结构   和枚举是值类型,而不是引用类型,而不是   通过引用存储和传递。

有一种方法可以防止实例取消初始化,从而造成泄漏。这称为强参考周期。看一下这个answer,你可以详细了解我现在的意思。

看看你的代码,我会这样做:

self.run(SKAction.group([fade, myScale], completion:  {
     [weak self] in
     guard let strongSelf = self else { return }
     strongSelf.removeFromParent()
}))

答案 1 :(得分:4)

是的,我想是的。

基本上有一件事需要检查是否会释放某些内存:

检查是否有任何其他对象包含对您正在检查的对象的强引用。

在这种情况下,您要检查您的Circle是否会从内存中释放。让我们看看哪些对象强烈引用Circle,从创建一个圆圈开始。

  1. 创建圆圈时,new变量包含强引用。方法createSprite返回后,此引用将中断。

  2. 当圆圈添加到场景中时,场景会对圆圈有强烈的引用。从场景中移除圆圈后,此参考将被破坏。

  3. 除此之外,我看不到对圆圈对象的任何其他强引用。所以你应该没事。

    此外,在Xcode 8中,还有一个新的内存调试功能。您也可以用它来检查它!

    只需运行您的应用,然后点击:

    enter image description here

    然后转到主编辑区,您应该看到这个(“TestingArea”是我的应用程序的名称):

    enter image description here

    现在,您可以通过单击应用程序名称右侧的按钮来查看您创建的对象的所有实例。就我而言,它是“TestingArea”右侧的按钮,即“AppDelegate”:

    enter image description here

    如果您在该列表中看到Circle,则表示您的应用在某处有Circle个对象。如果没有,内存中没有Circle

答案 2 :(得分:3)

显然已经足够了,虽然self.run(myScale)没有任何意义,因为Sprite已经从你的场景中删除了。

另外,我建议使用不同的方法:

self.run(fade, completion: {
  self.removeFromParent()
})

这更明确地显示了操作完成后会发生什么。