SKAction 运行块中的 SpriteKit 内存泄漏

SpriteKit memory leak in SKAction runblock

我在取消初始化场景后发现以下代码存在内存泄漏:

didMove 场景:

run(SKAction.repeatForever(SKAction.sequence([SKAction.wait(forDuration: 1.5), SKAction.run { [unowned self] in self.generateWave() }])))

函数:

func generateWave()
{
    let bgImage = self.childNode(withName: "bgImage") as! SKSpriteNode

    let waveNode = SKSpriteNode(texture: atlasSplashScreen.textureNamed("SplashScreenWave"))

    waveNode.position = CGPoint(x: -207, y: -60.8)

    bgImage.addChild(waveNode)

    let waveMove = SKAction.moveTo(x: self.frame.width / 2, duration: 6)

    waveNode.run(waveMove)
    {
        waveNode.removeFromParent()
    }

}

将最后一行更改为此修复泄漏:

waveNode.run(SKAction.sequence([waveMove, SKAction.removeFromParent()]))

知道我做错了什么吗?我以为我正确地处理了 weak/unowned 的东西,但现在我不确定。我不明白为什么将 removeFromParent 行放在完成块中会导致泄漏。

提前致谢。

麦克

waveNode 正在创建对自身的强引用。您可以取消拥有该引用,因为它只会将其引用计数减 1(它已经 1 太高了)。在这种特殊情况下,似乎没有像 Knight0fDragon 所引用的那样的问题,因为此 runBlock 用于删除您的对象本身;但是,如果它设置了弱强舞蹈,例如:

[weak waveNode] in

guard let waveNode = waveNode else { return }

Apple 在他们的 WWDC 的第 31:00 分钟就内存调试讨论了这个问题,从 2 年前开始;社区似乎倾向于关注自我弱点问题,而不是视频中的这些 "smaller leaks." Link:https://developer.apple.com/videos/play/wwdc2016/410/