TLTR:
问题: SKScene
子类的init(fileNamed:)
回报nil
原因:第二.sks
次初始化调用时文件不存在。该问题在某种程度上与ODR实施和/或行为有关。
描述:
用SpriteKit
. 我SKScene
的子类的init(fileNamed:)
回报nil
。我试图理解“为什么?” 如何?” 调试此问题。
我的初始化SKScene
子类的代码:
/// the hierarchy: SKScene -> TBTBaseScene -> TBTLevelScene
let sceneType: TBTBaseScene.Type = TBTLevelScene.self
let fileName = "Level1"
let scene = sceneType.init(fileNamed: fileName)
有几点需要注意:
- 此代码在运行时的某个时间点起作用,但在其他时间点不起作用。
- 当通过 Xcode 构建目标时,转到 Products -> AppName.app,右键单击“Show in Finder”,没有
Level1.sks
。也许没关系,因为应用程序使用ODR并Level1.sks
标有“Level1”标签,即使它位于初始安装标签中 - 当断点设置为
let sceneType:...
line 时,我可以通过相应的子类和文件名轻松创建其他游戏场景,但expression TBTLevelScene(fileName:"Level1")
返回nil
. - 我试图检查
Level1.sks
主捆绑包中是否存在,但对于所有场景,下面的代码总是说“文件不可用”,所以这种方法似乎是错误的。 - 游戏的场景加载架构由DemoBots 示例代码驱动。您可以在 中看到类似的方法
LoadSceneOperation.swift
。但是,那里的初始化在所有情况下都可以正常工作。
基于此答案,我用来检查“Level1”或“Level1.sks”的代码是否存在:
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 标签。该标签位于Initial Install Tags预取组中。
ORD 实现中肯定存在一些错误,它会在不需要时释放资源 ( Level1.sks
),并且不会在需要时再次加载它。我会继续努力弄清楚。(似乎到目前为止,SO 社区与此无关)