造成这种情况的原因有几个,我的游戏也遇到了类似的问题。如果操作正确,则无需删除纹理等内容。删除每个场景更改上的纹理也不理想,您希望将它们保留在内存中以提高性能,这样就不必每次都重新加载。
这是一个基本检查表,您可以使用它来查看是否造成内存泄漏。
1)将带有 print 语句的 deinit 方法添加到每个场景/类。如果 deinit 被调用,则您的场景已正确解除分配。
deinit {
print("Deinit GameScene")
}
2)您是否通过在两个类之间创建引用来在某处创建强引用循环?
Apple 强引用循环的经典示例
class Person {
var dog: Dog?
}
class Dog {
var person: Person?
}
要修复它,您必须使这 2 个属性中的 1 个变弱
class Person {
var dog: Dog?
}
class Dog {
weak var person: Person?
}
选项的良好实践是当不再需要它们时将它们设置为零。
person = nil
也许查看 google 和 Apple Swift 文档以了解如何处理此问题。前段时间我也问过类似的问题
Swift SpriteKit ARC 傻瓜版 https://stackoverflow.com/questions/35798496/swift-spritekit-arc-for-dummies
3)你使用闭包吗?它们可能会导致内存泄漏。
SpriteKit 中更常见的场景是这两个示例,它们可能/将导致内存泄漏并使场景无法释放。 (动作 2 是捕获 self 的闭包)
// Example 1
let action1 = SKAction.wait(forDuration: 1)
let action2 = SKAction.run(someMethod)
let sequence = SKAction.sequence([action1, action2])
run(SKAction.repeatForever(sequence))
// Example 2
let action1 = SKAction.wait(forDuration: 1)
let action2 = SKAction.run {
self.someMethod()
}
let sequence = SKAction.sequence([action1, action2])
run(SKAction.repeatForever(sequence))
一个好的经验法则是,当编译器强制您使用 self 时,您很可能会在不使用weak/unowned 的情况下造成内存泄漏。
因此,要修复上述 2 个 SKAction 示例,您可以确保在更改场景时始终删除所有操作,或者在我看来,最好将代码更改为此,以避免首先产生内存泄漏。
let action1 = SKAction.wait(forDuration: 1)
let action2 = SKAction.run { [weak self] in
self?.someClassMethod()
}
let sequence = SKAction.sequence([action1, action2])
run(SKAction.repeatForever(sequence))
请注意,在上面的所有示例中,您也可以编写
.... { [unowned self] in
比你不需要使用 ?在闭包中
self.someMethod()
当你使用 unowned 时,你基本上说 self 永远不会为零,如果调用闭包时它实际上是 nil ,则可能会导致崩溃。如果您使用weak self,您会告诉编译器在调用闭包之前self可能会变成nil,因此self是避免崩溃的可选选项。
我认为使用“弱”而不是“无主”来避免这种情况几乎总是更好。在我的一款游戏中,我在从 iTunes 获取 StoreKit 产品时调用的闭包中使用了 unowned self。这导致我发生了微妙的崩溃,因为我可以在调用闭包之前退出 SKScene。如果你使用弱自我,你不会崩溃,因为你使用了选项。
希望这个对你有帮助