У меня проблема с извлечением управляемого объекта Core Data, который имеет атрибут enum
с Int16
rawValues. Сбой программы при вызове NSPredicate(format:)
.
. Этот код (3-я строка) приводит к появлению сообщения cra sh:
func returnBook (bookType: BookType) -> Book? {
let fetchRequest = NSFetchRequest<Book>(entityName: "Book")
fetchRequest.predicate = NSPredicate(format: "%K = %@", #keyPath(Book.bookType), bookType.rawValue as CVarArg)
fetchRequest.fetchLimit = 1
let book = (try? fetchRequest.execute())?.first
return book
}
Cra sh:
Поток 1: EXC_BAD_ACCESS (код = 1, адрес = 0x3)
Когда я изменяю 3-ю строку следующим образом, я получаю еще один вид ошибки.
Это альтернативный код:
fetchRequest.predicate = NSPredicate(format: "%K = %@", #keyPath(Book.bookType), bookType as! CVarArg)
И это ошибка, вызванная этим альтернативным кодом:
Поток 1: сигнал SIGABRT
И я вижу это в выходных данных отладки:
Не удалось преобразовать значение типа 'ProjectName.BookType' (0x10ac10098) в 'Swift.CVarArg' (0x10b698548).
Вот еще некоторый связанный код в Проекте:
@objc(Book)
public class Book: NSManagedObject {
// …
}
extension Book {
@NSManaged public var bookType: BookType
}
@objc public enum BookType: Int16 {
case fiction = 0
case nonFiction = 1
case reference = 2
}
Мой вопрос: Как правильно извлечь объект Book
из моего хранилища основных данных, используя его bookType
атрибут, который имеет тип @objc enum
с Int16
rawValues?
Обновление:
Я пробовал что-то еще в качестве подсказки d в презентации Джесси Сквайрс:
- Удалено ключевое слово
@objc
из определения enum
- Используется
private
и public
свойства для доступа к экземплярам enum
...
Я изменил свой код, как предложено в связанной презентации, и я изменил имя атрибута bookType
в Базовых данных ".xcdatamodeld "file to bookTypeValue
.
extension Book {
public var bookType: BookType {
get {
return BookType(rawValue: self.bookTypeValue)!
}
set {
self.bookTypeValue = newValue.rawValue
}
}
@NSManaged private var bookTypeValue: Int16
}
public enum BookType: Int16 {
case fiction = 0
case nonFiction = 1
case reference = 2
}
И я попытался извлечь, используя личное значение, как предложено в презентации, связанной выше ...:
fetchRequest.predicate = NSPredicate(format: "bookTypeValue == %@", bookType)
Однако я не мог решить моя проблема с этим методом также ... XCode немедленно жалуется:
Тип аргумента 'BookType' не соответствует ожидаемому типу 'CVarArg'
XCode прекращает жаловаться, если я используйте вместо этого bookType.rawValue
. Однако во время выполнения программа вылетает с той же ошибкой, что и выше (первая).
Обновление 2:
Я применил ответы, данные этот вопрос , который предлагается сообществом. Чтобы быть более точным c, я попробовал предложение в ответе на этот вопрос, который использует %i
или @ld
вместо %@
, например, так:
fetchRequest.predicate = NSPredicate(format: "bookTypeValue == %i", bookType.rawValue)
, и у меня есть попробовал другое предложение, использующее интерполяцию строк следующим образом:
fetchRequest.predicate = NSPredicate(format: "bookTypeValue == %@", "\(bookType.rawValue)")
Эти изменения кода предотвратили сбои, но fun c returnBook
возвращает ноль, даже если я уверен, что данные есть. Выборка или сравнение по какой-то причине не удается ...