Apple在https://developer.apple.com/documentation/spritekit/skscenedelegate中声明:
在规定的回调之外修改SpriteKit对象(a 可以导致后台队列或其他任何非主线程) 并发相关问题。 甚至在主线程上调度工作 异步或稍后是有风险的,因为关闭是 可能是在SpriteKit期望的时间范围之外完成的。如果 您遇到了分段错误或其他类型的崩溃 发生在SpriteKit框架深处,这是一个很好的机会 你的代码正在修改普通的SpriteKit对象 回调。
我使用手势识别器与我的精灵工具包对象进行交互。一个简单的例子是当用户点击一个对象时向节点添加一个SKAction:
func tapAction(gr:UITapGestureRecognizer) {
scene.childNode(withName: "balloon")!.run(SKAction.fadeOut(withDuration: 2))
}
尽管这个"正常运作"目前,我担心这在更复杂的情况下不起作用。
Apple是否允许这样做?或者我是否真的必须将SpritKit对象的修改从手势动作推迟到规定的回调?
答案 0 :(得分:5)
看起来你很安全,你只是分配一个动作。这将在正常的精灵套件更新期间运行
如果您正在操作实际对象或删除节点,则会出现问题。假设你点击删除一个节点。此点击发生在didContactBegin
之前。 didContactBegin
会期望一个节点,但是唉,你删除它,所以它会崩溃。
如果您对此感到安全,请在更新开始时设置要触发的队列。
class GameScene : SKScene
{
public typealias Closure = ()->()
public var processOnUpdate = [Closure]()
override func update(_ currentTime: TimeInterval) {
proceseOnUpdate.forEach{$0()}
processOnUpdate = [Closure]()
....//do other stuff
}
}
//SKView Code
func tapAction(gr:UITapGestureRecognizer) {
scene.processOnUpdate.append(
{
scene.childNode(withName: "balloon")!.run(SKAction.fadeOut(withDuration: 2))
}}
}
如果第一次没有运行,我很抱歉,我现在不在Mac上测试它。