调试为什么SKScene init(fileNamed :)返回nil

Yev*_*nin 3 xcode ios sprite-kit swift on-demand-resources

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)
Run Code Online (Sandbox Code Playgroud)

几点注意事项:

  1. 此代码在运行时期间的某个时刻起作用,但在另一个时则不起作用.
  2. 当目标通过Xcode构建时,转到Products - > AppName.app,右键单击"Show in Finder",没有Level1.sks.也许没关系,因为该应用程序使用ODRLevel1.sks标记为"Level1"标记,即使它位于初始安装标记中
  3. 当断点设置为let sceneType:...line时,我可以通过各自的子类和fileNames轻松创建其他游戏场景,但expression TBTLevelScene(fileName:"Level1")返回nil.
  4. 我试图检查Level1.sks主捆绑中是否存在,但是对于所有场景,ALWAYS下面的代码都说"FILE NOT AVAILABLE",所以这种方法似乎是错误的.
  5. 游戏的场景加载架构由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")
}
Run Code Online (Sandbox Code Playgroud)

更新:

检查所提供的文件的方法迈克尔Dautermann做工作,它样张的原因:Level1.sks没有没有第二次尝试加载过程中存在.

Level1.sks项目中的文件将添加到"复制包资源"区域,并具有"Level1"ODR标记.标签位于初始安装标签预取组中.

在ORD实现中肯定存在一些错误,Level1.sks它在不需要时处理resource()并且在需要时不再加载它.我会继续努力弄明白.(似乎,SO社区到目前为止与此无关)

Mic*_*ann 5

这里有一些事情正在发生,但最终发生的事情是,听起来你的" 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")
}
Run Code Online (Sandbox Code Playgroud)

2)

确保将.sks文件复制到您构建的应用程序中.

打开目标的"Build Phases"部分,然后单击"Copy Bundle Resources"区域.确保您的.sks文件包含在其中.