【发布时间】:2016-03-31 11:10:15
【问题描述】:
TLTR:
问题: SKScene 子类的init(fileNamed:)returns 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:...行时,我可以通过相应的子类和文件名轻松创建其他游戏场景,但expression TBTLevelScene(fileName:"Level1")返回nil。 - 我尝试检查主包中是否有
Level1.sks,但对于所有场景,下面的代码总是显示“文件不可用”,因此该方法似乎是错误的。 - 游戏的场景加载架构由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 标签。标签位于 Initial Install Tags 预取组中。
在 ORD 实现中肯定存在一些错误,它会在不需要时释放资源 (Level1.sks),并且在需要时不会再次加载它。我会继续努力弄清楚。 (目前看来,SO 社区与此无关)
【问题讨论】:
标签: ios xcode swift sprite-kit on-demand-resources