当数据不再匹配谓词时 NSFetchedResultsControllerDelegate 不被调用
NSFetchedResultsControllerDelegate not called when data is not matching predicate anymore
我试图解决的问题如下:NSFetchedResultsController 的谓词将结果限制为特定条件。但是当数据对象新满足或不满足条件时, NSFetchedResultsControllerDelegate 不会被调用。
我的 NSFetchedResultsController:
private var _fetchedResultsController : NSFetchedResultsController<CardIndex>? = nil
var fetchedResultController : NSFetchedResultsController<CardIndex> {
get {
if _fetchedResultsController == nil {
let fetchRequest: NSFetchRequest<CardIndex> = CardIndex.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor.init(key: "index", ascending: true)]
fetchRequest.predicate = NSPredicate.init(format: "consumer == %@ AND card.definition != nil AND card.stateInt == 0", consumer)
_fetchedResultsController = NSFetchedResultsController<CardIndex>.init(fetchRequest: fetchRequest, managedObjectContext: CDManager.shared.one.viewContext, sectionNameKeyPath: nil, cacheName: nil)
do {
try _fetchedResultsController?.performFetch()
} catch {
Log(.Warning, "...")
}
_fetchedResultsController?.delegate = self
}
return _fetchedResultsController!
}
}
这里相关的数据结构(仅伪代码):
class CardIndex {
@NSManaged public var index: Int16
@NSManaged public var consumer: String?
@NSManaged public var card: CardApplication?
}
class CardApplication {
@NSManaged public var title: String?
@NSManaged public var indexes: NSSet?
@NSManaged public var stateInt: NSNumber?
@NSManaged public var definition: CardDefinition?
}
当 NSFetchedResultsController 最初获取数据时,它正确地 returns 所有具有 definition
集的 CardApplication
并且 stateInt
的值为 0
.但是,当我在运行时将 stateInt
的值更改为另一个不再匹配谓词条件的值时,不会调用 NSFetchedResultsControllerDelegate 以反映数据中的更改。我确保在更改 stateInt
值后保存托管对象的上下文,我还可以看到保存前的上下文 hasChanges
和 CardApplication
托管对象也显示 属性 changedValues()
。在保存更改之前从调试器控制台,其中 self 是我更改 stateInt
的 CardApplication
对象:
(lldb) po managedObjectContext!.hasChanges
true
(lldb) po self.isUpdated
true
(lldb) po self.changedValues()
▿ 1 element
▿ 0 : 2 elements
- key : "stateInt"
- value : 1
为什么委托没有被调用?
由于您的 FRC 配置为获取 CardIndex 对象,因此它只会观察这些对象的变化。因此,它不会响应对相关 CardApplication 对象的更改。您可以故意“弄脏” CardIndex,这将触发 FRC 重新评估谓词,或者放弃 FRC 并使用您自己的观察者来更新您的 UI.
我试图解决的问题如下:NSFetchedResultsController 的谓词将结果限制为特定条件。但是当数据对象新满足或不满足条件时, NSFetchedResultsControllerDelegate 不会被调用。
我的 NSFetchedResultsController:
private var _fetchedResultsController : NSFetchedResultsController<CardIndex>? = nil
var fetchedResultController : NSFetchedResultsController<CardIndex> {
get {
if _fetchedResultsController == nil {
let fetchRequest: NSFetchRequest<CardIndex> = CardIndex.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor.init(key: "index", ascending: true)]
fetchRequest.predicate = NSPredicate.init(format: "consumer == %@ AND card.definition != nil AND card.stateInt == 0", consumer)
_fetchedResultsController = NSFetchedResultsController<CardIndex>.init(fetchRequest: fetchRequest, managedObjectContext: CDManager.shared.one.viewContext, sectionNameKeyPath: nil, cacheName: nil)
do {
try _fetchedResultsController?.performFetch()
} catch {
Log(.Warning, "...")
}
_fetchedResultsController?.delegate = self
}
return _fetchedResultsController!
}
}
这里相关的数据结构(仅伪代码):
class CardIndex {
@NSManaged public var index: Int16
@NSManaged public var consumer: String?
@NSManaged public var card: CardApplication?
}
class CardApplication {
@NSManaged public var title: String?
@NSManaged public var indexes: NSSet?
@NSManaged public var stateInt: NSNumber?
@NSManaged public var definition: CardDefinition?
}
当 NSFetchedResultsController 最初获取数据时,它正确地 returns 所有具有 definition
集的 CardApplication
并且 stateInt
的值为 0
.但是,当我在运行时将 stateInt
的值更改为另一个不再匹配谓词条件的值时,不会调用 NSFetchedResultsControllerDelegate 以反映数据中的更改。我确保在更改 stateInt
值后保存托管对象的上下文,我还可以看到保存前的上下文 hasChanges
和 CardApplication
托管对象也显示 属性 changedValues()
。在保存更改之前从调试器控制台,其中 self 是我更改 stateInt
的 CardApplication
对象:
(lldb) po managedObjectContext!.hasChanges
true
(lldb) po self.isUpdated
true
(lldb) po self.changedValues()
▿ 1 element
▿ 0 : 2 elements
- key : "stateInt"
- value : 1
为什么委托没有被调用?
由于您的 FRC 配置为获取 CardIndex 对象,因此它只会观察这些对象的变化。因此,它不会响应对相关 CardApplication 对象的更改。您可以故意“弄脏” CardIndex,这将触发 FRC 重新评估谓词,或者放弃 FRC 并使用您自己的观察者来更新您的 UI.