【问题标题】:Children of a Scene not releasing fast enough?场景的孩子没有足够快地释放?
【发布时间】:2016-11-30 13:30:35
【问题描述】:

在一个场景中有几个子节点,然后快速过渡到一个新场景。

在新场景中,didMove(to view: ….) 用于将前一个场景的孩子添加到下一个场景中。

快速执行此操作时,SceneKit 崩溃,似乎是因为旧场景的子级尚未释放。

如果我在将孩子添加到第二个场景之前添加一点延迟,那很好……看起来 SpriteKit 释放孩子的速度不够快,无法进行场景转换。

以上是关于这个问题的目的最重要的理解。我(错误地)假设 SpriteKit 会确保在尝试将它们添加到后续场景之前释放附加到场景的所有节点。它不这样做。但它确实释放了它们,只是需要一点时间。这是一帧吗?一秒?不知道...

我的场景过渡时间是 0.25 秒

还尝试在原始场景中使用willMove(to view: ….) 手动移除孩子。这也不起作用,看似相同的行为:不够快。

还尝试假设孩子仍然与其父母有关系,因此尝试移动到其新父母,新场景,move(toParent:…) 这也会崩溃。所以也许孩子们已经被标记为即将被释放,我想。

是否知道,如果知道,如何处理?

【问题讨论】:

  • 您不能在 移动到场景之前将孩子添加到场景中吗?我认为这会产生最快的结果。
  • 所以从一个中删除,然后添加,然后切换场景?
  • 啊,这是一个有趣的方法。我刚刚弄清楚moveTo( 的实际工作原理......对于这种情况来说,它不够理想和纯粹。但可以在其他情况下使用。
  • 您总是希望尽可能多地预加载以减少加载时间(例如 didMoveToView)。我无法具体说明为什么您在没有项目文件的情况下会崩溃。您能否在新项目中始终如一地重现这种情况(例如出现错误)?
  • 我正在一个框架项目中创建菜单,所以是的......它是完全可重现的,问题中的步骤显示了我在隔离和确定问题方面的尝试。

标签: ios swift sprite-kit skscene


【解决方案1】:

您不能在同一帧(SK 循环)中同时呈现一个场景并拥有 willMove 函数——您的下一个场景的 viewDidLoad 将在前一个场景被销毁之前被调用。在调用 presentScene 之前,您必须删除所有节点:

我建议创建某种全局变量来访问您的SKView;有了它,您可以从任何地方控制您的场景:

currentScene.removeAllChildren()
gView!.presentScene(nextScene)

【讨论】:

【解决方案2】:

“这是已知的吗?如果是,如何处理?”

是的,这是 SceneKit 和 IOS 设计和操作范式的一个已知问题。认为场景必须始终存在并在屏幕上。没有屏幕上的场景就没有时间。

因此,在过渡期间的短暂时间内,两个场景都已加载并处于活动状态。

解决这个问题有三种方法:

  • 在执行过渡之前从旧场景中删除所有内容,以便didMove(to view...中的新场景可以立即加载它

  • 等待过渡完成,然后再将旧场景中的任何内容加载到新场景中,这样就不会出现孩子的所有权冲突。

  • KnightOfDragon 的第一个建议是使用.copy(),因此场景中不会出现相同的实例。

【讨论】:

  • 或者您可以在移动到下一个场景之前加载所有内容,正如我最初建议的那样。或者,在下一个场景的过渡中,您可以在解除分配之前删除所有内容。所以至少有 5 种方式。
  • ...或者只是不处理全局设计模式哈哈哈
  • @Knight0fDragon 非全球性世界的外观和工作方式如何?
  • 我不知道,我猜这需要做很多工作,我需要看看你的代码。
  • 这就是我对大多数“正确”OOP 实践的看法……很多工作。我如何找到您的电子邮件地址?
猜你喜欢
  • 1970-01-01
  • 2011-07-31
  • 2015-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多