[英]Issue with fetching Core Data managed object using NSPredicate by object's enum attribute
我在获取具有Int16
rawValues 的enum
属性的 Core Data 托管对象时遇到问题。 调用NSPredicate(format:)
时程序崩溃。
这是导致崩溃的代码(第 3 行):
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
}
崩溃消息是:
线程 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
}
我的问题:如何使用bookType
属性从我的 Core Data 存储中正确获取Book
对象,该属性位于具有Int16
rawValues 的@objc enum
类型中?
更新:
我已经按照 Jesse Squires 的演示文稿中的建议尝试了其他方法:
enum
的定义中删除了@objc
关键字private
和public
属性来访问enum
的实例... 我已按照链接演示文稿中的建议更改了代码,并将 Core Data 的“.xcdatamodeld”文件中的bookType
属性名称更改为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”
如果我改用bookType.rawValue
XCode 就会停止抱怨。 但是,程序在运行时崩溃并出现上述相同的错误(第一个)。
更新 2:
我已经应用了社区建议的这个问题的答案。 更具体地说,我在使用%i
或@ld
而不是%@
问题的答案中尝试了建议,如下所示:
fetchRequest.predicate = NSPredicate(format: "bookTypeValue == %i", bookType.rawValue)
我已经尝试了另一个使用字符串插值的建议,如下所示:
fetchRequest.predicate = NSPredicate(format: "bookTypeValue == %@", "\(bookType.rawValue)")
这些代码更改防止了崩溃,但 func returnBook
返回 nil,即使我确定数据在那里。 由于某种原因,获取或比较失败...
在为这个问题苦苦挣扎了几个小时后,我终于设法解决了它。
以下是我为按时间顺序解决问题所做的工作:
bookTypeValue
的类型从Int16
更改为Int32
,因为我在官方(存档) 文档中看不到 16 位整数的格式说明符。 我已经测试过,我可以确认,如果您在此处使用%@
而不是正确的格式说明符(对于有符号 32 位整数是%d
,您会得到问题中的第一个错误:线程 1:EXC_BAD_ACCESS(代码=1,地址=0x3)
我已经更改了NSPredicate(format:)
调用,如下所示:
fetchRequest.predicate = NSPredicate(格式:"bookTypeValue == %d", bookType.rawValue)
我已经更改了returnBook
func 中的第 5 行, returnBook
所示:
do { let results = try coreDataStack.managedContext.fetch(fetchRequest) if results.count > 0 { book = results.first return book } } catch let error as NSError { print("Fetch error: \\(error) description: \\(error.userInfo)") }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.