Отладка, почему 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)

Несколько вещей, чтобы отметить:

  1. Этот код работает в какой-то момент во время выполнения, но не работает в другой.
  2. Когда цель создается с помощью XCode, перейдя в Products -> AppName.app, щелкните правой кнопкой мыши "Показать в Finder", там НЕТ Level1.sks, Возможно, это нормально, потому что приложение использует ODR и Level1.sks помечен тегом "Level1", хотя он находится в тегах начальной установки
  3. Когда точка останова установлена ​​на let sceneType:... линия, я мог бы легко создавать другие игровые сцены через соответствующие подклассы и fileNames, но expression TBTLevelScene(fileName:"Level1") возвращается nil,
  4. Я пытался проверить, есть ли Level1.sks в основном пакете, но код ниже ВСЕГДА говорит "ФАЙЛ НЕ ДОСТУПЕН" для всех сцен, поэтому подход кажется неправильным.
  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")
}

ОБНОВИТЬ:

Подход для проверки файлов, предоставленный Michael Dautermann, действительно работает, и это доказывает причину: Level1.sks не существует во время второй попытки загрузить его.

Level1.sks Файл в проекте добавляется в область "Копировать ресурсы комплекта" и имеет тег ODR "Level1". Тег находится в группе предварительно выбранных тегов начальной установки.

Существует определенная ошибка в реализации ORD, которая удаляет ресурс (Level1.sks) когда он не нужен и не загружает его снова в то время, когда это требуется. Я буду продолжать двигаться, чтобы понять это. (Похоже, SO сообщество пока не имеет к этому никакого отношения)

1 ответ

Решение

Здесь происходит несколько вещей, но в конечном итоге это звучит как вашаLevel1msgstr "файл не заканчивается во встроенном приложении.

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 включен туда.

Другие вопросы по тегам