调试为什么 SKScene init(fileNamed:) returns nil
Debug why SKScene init(fileNamed:) returns nil
TLTR:
问题: SKScene
子类的 init(fileNamed:)
returns nil
原因:第二次初始化调用时.sks
文件不存在。这个问题在某种程度上与 ODR 实施 AND/OR 行为有关。
描述:
使用 SpriteKit
构建的游戏。我的 SKScene
子类的 init(fileNamed:)
returns nil
。我试图理解 "why?" 和 "how?" 来调试这个问题。
我初始化 SKScene
子类的代码:
/// the hierarchy: SKScene -> TBTBaseScene -> TBTLevelScene
let sceneType: TBTBaseScene.Type = TBTLevelScene.self
let fileName = "Level1"
let scene = sceneType.init(fileNamed: fileName)
注意事项:
- 此代码在运行时的某个时间点有效,但在另一个时间点无效。
- 通过 Xcode 构建目标时,转到产品 -> AppName.app,右键单击,"Show in Finder",没有
Level1.sks
。也许没关系,因为应用程序使用 ODR 并且 Level1.sks
标记有 "Level1" 标签,即使它在 Initial Install Tags
- 当断点设置到
let sceneType:...
行时,我可以通过各自的子类和文件名轻松创建其他游戏场景,但是 expression TBTLevelScene(fileName:"Level1")
returns nil
.
- 我试图检查主包中是否有
Level1.sks
,但下面的代码对于所有场景总是显示 "FILE NOT AVAILABLE",所以该方法似乎是错误的。
- 游戏的场景加载架构由 DemoBots Sample Code 驱动。您可以在
LoadSceneOperation.swift
中看到类似的方法。不过,那里的初始化在所有情况下都可以正常工作。
我用来检查 "Level1" 或 "Level1.sks" 是否存在的代码,基于 this answer:
let path = NSBundle.mainBundle().bundlePath
let url = NSURL(fileURLWithPath: path)
let filePath = url.URLByAppendingPathComponent(fileName).absoluteString
let fileManager = NSFileManager.defaultManager()
if fileManager.fileExistsAtPath(filePath) {
print("FILE AVAILABLE")
} else {
print("FILE NOT AVAILABLE")
}
更新:
Michael Dautermann 提供的检查文件的方法确实有效,它证明了原因:Level1.sks
在第二次尝试加载它时 不 存在。
项目中的Level1.sks
文件被添加到"Copy Bundle Resources"区域并具有"Level1" ODR标签。该标签位于 初始安装标签 预取组中。
ORD 实现中肯定存在一些错误,该错误会在不需要时处理资源 (Level1.sks
),并且在需要时不会再次加载它。我会继续努力弄清楚。 (似乎,到目前为止,SO 社区与此无关)
这里发生了一些事情,但最终发生的事情是听起来您的“Level1
”文件没有在构建的应用程序中结束。
1)
你的文件存在检查代码混合文件 URL 和文件路径太多了。将您的代码更改为如下所示:
// if nodePath is nil, then it's not found in the bundle
if let nodePath = NSBundle.mainBundle().pathForResource("Level1", ofType: "sks")
{
print("FILE AVAILABLE")
} else {
print("FILE NOT AVAILABLE")
}
2)
确保您的 .sks 文件被复制到您构建的应用程序中。
打开目标的 "Build Phases" 部分和 click on the "Copy Bundle Resources" area。确保您的 .sks 文件包含在其中。
TLTR:
问题: SKScene
子类的 init(fileNamed:)
returns nil
原因:第二次初始化调用时.sks
文件不存在。这个问题在某种程度上与 ODR 实施 AND/OR 行为有关。
描述:
使用 SpriteKit
构建的游戏。我的 SKScene
子类的 init(fileNamed:)
returns nil
。我试图理解 "why?" 和 "how?" 来调试这个问题。
我初始化 SKScene
子类的代码:
/// the hierarchy: SKScene -> TBTBaseScene -> TBTLevelScene
let sceneType: TBTBaseScene.Type = TBTLevelScene.self
let fileName = "Level1"
let scene = sceneType.init(fileNamed: fileName)
注意事项:
- 此代码在运行时的某个时间点有效,但在另一个时间点无效。
- 通过 Xcode 构建目标时,转到产品 -> AppName.app,右键单击,"Show in Finder",没有
Level1.sks
。也许没关系,因为应用程序使用 ODR 并且Level1.sks
标记有 "Level1" 标签,即使它在 Initial Install Tags - 当断点设置到
let sceneType:...
行时,我可以通过各自的子类和文件名轻松创建其他游戏场景,但是expression TBTLevelScene(fileName:"Level1")
returnsnil
. - 我试图检查主包中是否有
Level1.sks
,但下面的代码对于所有场景总是显示 "FILE NOT AVAILABLE",所以该方法似乎是错误的。 - 游戏的场景加载架构由 DemoBots Sample Code 驱动。您可以在
LoadSceneOperation.swift
中看到类似的方法。不过,那里的初始化在所有情况下都可以正常工作。
我用来检查 "Level1" 或 "Level1.sks" 是否存在的代码,基于 this answer:
let path = NSBundle.mainBundle().bundlePath
let url = NSURL(fileURLWithPath: path)
let filePath = url.URLByAppendingPathComponent(fileName).absoluteString
let fileManager = NSFileManager.defaultManager()
if fileManager.fileExistsAtPath(filePath) {
print("FILE AVAILABLE")
} else {
print("FILE NOT AVAILABLE")
}
更新:
Michael Dautermann 提供的检查文件的方法确实有效,它证明了原因:Level1.sks
在第二次尝试加载它时 不 存在。
项目中的Level1.sks
文件被添加到"Copy Bundle Resources"区域并具有"Level1" ODR标签。该标签位于 初始安装标签 预取组中。
ORD 实现中肯定存在一些错误,该错误会在不需要时处理资源 (Level1.sks
),并且在需要时不会再次加载它。我会继续努力弄清楚。 (似乎,到目前为止,SO 社区与此无关)
这里发生了一些事情,但最终发生的事情是听起来您的“Level1
”文件没有在构建的应用程序中结束。
1)
你的文件存在检查代码混合文件 URL 和文件路径太多了。将您的代码更改为如下所示:
// if nodePath is nil, then it's not found in the bundle
if let nodePath = NSBundle.mainBundle().pathForResource("Level1", ofType: "sks")
{
print("FILE AVAILABLE")
} else {
print("FILE NOT AVAILABLE")
}
2)
确保您的 .sks 文件被复制到您构建的应用程序中。
打开目标的 "Build Phases" 部分和 click on the "Copy Bundle Resources" area。确保您的 .sks 文件包含在其中。