iOS9 Swift spritekit, фатальная ошибка SKEmitterNode: неожиданно найдено nil при развертывании необязательного значения

безуспешно работая над этим кодом в течение нескольких часов, пожалуйста, посоветуйте:

Я создаю игру spritekit для iOS 9. Этот метод:

func createFiringParticles(location:CGPoint, force:CGVector){

    let fireEmitter = SKEmitterNode(fileNamed: "FireParticles")

    fireEmitter!.position = location
    fireEmitter!.name = "fireEmitter"
    fireEmitter!.zPosition = 1
    fireEmitter!.targetNode = self
    fireEmitter!.numParticlesToEmit = 50

    fireEmitter!.xAcceleration = force.dx
    fireEmitter!.yAcceleration = -force.dy

    self.addChild(fireEmitter!)

}

выдает эту ошибку: фатальная ошибка: неожиданно найдено nil при распаковке необязательного значения

ошибка сначала не инициируется (поэтому она работает несколько минут, пока не рухнет). Я попытался развернуть SKEmitterNode с помощью NSKeyedUnarchiver:

    var unWrappedFireEmitter = NSBundle.mainBundle().pathForResource("FireParticles", ofType: "sks")!
    var fireEmitter = NSKeyedUnarchiver.unarchiveObjectWithFile(unWrappedFireEmitter) as! SKEmitterNode
    fireEmitter.position = location
    fireEmitter.name = "fireEmitter"
    ..........
    self.addChild(fireEmitter)

без всякого успеха. как развернуть SKEmitterNode? это что-то в файле sks? введите описание изображения здесь большое спасибо за помощь!!!!


person ohad    schedule 17.09.2015    source источник
comment
Вы принудительно разворачиваете (!). Если необязательная переменная nil, это не даст вам волшебным образом действительный экземпляр. Вам нужно убедиться, что это не nil перед принудительной распаковкой. Это очень простой материал, я думаю, вам следует как минимум прочитать книгу Swift: itunes.apple.com/jp/book/swift-programming-language/   -  person Nicolas Miari    schedule 17.09.2015
comment
В вашем конкретном случае NSBundle... вполне может вернуть nil: например, вы указали путь к несуществующему файлу для чтения.   -  person Nicolas Miari    schedule 17.09.2015


Ответы (1)


NSKeyedUnarchiver.unarchiveObjectWithFile() выдает исключение, потому что ожидает в качестве аргумента строку, отличную от nil (тип: String), а вы передаете необязательную строку (т. е. тип String?) и принудительно разворачиваете ее, когда она просто содержит nil ("вообще нет значения") вместо действительного значения.

Похоже, это происходит из-за того, что более ранний вызов NSBundle.mainBundle().pathForResource(_:, ofType:) должен быть неудачным (путь не может быть найден среди ваших ресурсов, т. е. указанный файл не существует).

В вашем конкретном случае этот код должен работать:

let optionalFireEmitter = NSBundle.mainBundle().pathForResource("FireParticles", ofType: "sks")

if let unWrappedFireEmitter = optionalFireEmitter {
    // you can use your unWrappedFireEmitter, no need to append "!"
    // (it is already unwrapped)

    // (...your code here...)
}
else{
    // NSBundle.mainBundle().pathForResource() returned nil: Can't use.
    // Make sure the file name and extension you specified are correct
    // and that the resource file is included in your binary.
}
person Nicolas Miari    schedule 17.09.2015
comment
спасибо, я уже пробовал этот способ, но это приводит к большему количеству ошибок (в 1000-строчном коде), мне нужно найти способ присвоить unwrappedFireEmitter ненулевое значение, если nil. - person ohad; 17.09.2015
comment
Какие именно ошибки? Это очень распространенный фрагмент кода. - person Nicolas Miari; 17.09.2015
comment
Если ваш pathForResource возвращает nil, вы ничего не можете сделать. Вы должны исправить имя или расширение, которые вы передали, и убедиться, что ваш проект имеет указанный ресурс. - person Nicolas Miari; 17.09.2015