Отладка, почему SKScene init(fileNamed:) возвращает ноль
транслятор:
Выпуск: 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, щелкните правой кнопкой мыши "Показать в Finder", там НЕТ
Level1.sks
, Возможно, это нормально, потому что приложение использует ODR иLevel1.sks
помечен тегом "Level1", хотя он находится в тегах начальной установки - Когда точка останова установлена на
let sceneType:...
линия, я мог бы легко создавать другие игровые сцены через соответствующие подклассы и fileNames, но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
Файл в проекте добавляется в область "Копировать ресурсы комплекта" и имеет тег ODR "Level1". Тег находится в группе предварительно выбранных тегов начальной установки.
Существует определенная ошибка в реализации ORD, которая удаляет ресурс (Level1.sks
) когда он не нужен и не загружает его снова в то время, когда это требуется. Я буду продолжать двигаться, чтобы понять это. (Похоже, SO сообщество пока не имеет к этому никакого отношения)
1 ответ
Здесь происходит несколько вещей, но в конечном итоге это звучит как вашаLevel1
msgstr "файл не заканчивается во встроенном приложении.
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 копируется в ваше встроенное приложение.
Откройте раздел "Этапы сборки" своей цели и нажмите на область "Копировать ресурсы комплекта". Убедитесь, что ваш файл.sks включен туда.