问题描述
在UUID
中使用NSManagedobject
的{{1}}属性时,应用程序崩溃:
-[__ NSConcreteUUID比较:]:无法识别的选择器已发送到实例
NSFetchedResultsController
的内容更改时,但第一次加载时不更改。首次加载时,对象会按UUID正确排序。
这就是我创建NSFetchedResultsController.fetchedobjects
的方式:
NSFetchedResultsController
要创建let fetchRequest: NSFetchRequest<MyObject> = MyObject.fetchRequest()
fetchRequest.sortDescriptors = [
NSSortDescriptor(key: #keyPath(MyObject.uuid),ascending: true),]
fetchRequest.predicate = nspredicate(format: "%K == %@",#keyPath(MyObject.tag),tag)
let controller = NSFetchedResultsController(fetchRequest: fetchRequest,managedobjectContext: context,sectionNameKeyPath: nil,cacheName: nil)
controller.delegate = self
do {
try controller.performFetch()
} catch {
fatalError("###\(#function): Failed to performFetch: \(error)")
}
(在上面的代码中为NSManagedobject
),我使用模型编辑器添加了类型为MyObject
的字段“ uuid”。
似乎Core Data在sql级别上按UUID排序没有问题,但是在加载数据并尝试在内存中维护排序之后,它会尝试在以下位置调用UUID
上的compare
某种方式,它不作为一种方法存在。可以通过比较UUID的字节或字符串来实现此方法。
尝试失败:
也许通过使用NSSortDescriptor
有一种解决方法,它将使它从sql端的本机UUID类型中受益,但仍可以在Transformable
内使用?
解决方法
否,无法使用UUID
属性对Core Data结果进行排序。如果要使用UUID进行排序,则需要将其转换为字符串。
获取时,核心数据实际上并未按UUID排序。如果通过在Xcode的构建方案中的参数中添加-com.apple.CoreData.SQLDebug 4
来打开Core Data SQLite调试,则可以看到此信息。当您对时间戳等数值属性进行排序时,调试输出将包含一个SQL ORDER BY
子句
CoreData: sql: SELECT 0,t0.Z_PK FROM ZEVENT t0 ORDER BY t0.ZTIMESTAMP DESC
如果您使用UUID
属性进行尝试,则没有ORDER BY
子句。核心数据只是忽略排序描述符。它不会崩溃,但也不会对结果进行排序。
我不确定为什么会这样,因为使用sqlite3
命令行工具打开Coreite创建的SQLite文件显示UUID属性表示为SQLite BLOB
字段。 SQLite可以对BLOB
进行排序,尽管这样做通常没有意义。
我建议向Apple提交错误。我不知道他们会如何考虑它的工作原理,但是它绝对不应该忽略排序描述符并且不打印某种控制台消息。