如何注意Core Data处理的Managed Object Entity的变化?
问题描述:
动机是在实体值发生变化时获得重新计算的触发器。如何注意Core Data处理的Managed Object Entity的变化?
我在下面引用的快速解决方案的工作,但它有缺点。这是低效的。
在实际的应用程序中,有数十个实体。其中任何一项的更改都会导致不必要的通知。如果可能,可以避免这些。
在此示例中,唯一的EmployeeMO感兴趣。没有其他实体需要遵守。
你的想法是什么?
let n = NotificationCenter.default
n.addObserver(self, selector: #selector(mocDidChange(notification:)),
name: NSNotification.Name.NSManagedObjectContextObjectsDidChange,
object: managedObjectContext)
@objc func mocDidChange(notification n: Notification) {
if n.isRelatedTo(as: EmployeeMO.self) {
// do recalculation
}
}
和扩展,以检查通知与给定管理对象:
extension Notification {
public func isRelatedTo<T>(as t: T.Type) -> Bool where T: NSManagedObject {
typealias S = Set<T>
let d = userInfo as! [String : Any]
return d[NSInsertedObjectsKey] is S ||
d[NSUpdatedObjectsKey] is S ||
d[NSDeletedObjectsKey] is S ||
d[NSRefreshedObjectsKey] is S ||
d[NSInvalidatedObjectsKey] is S
}
}
的Xcode 9 Beta版,雨燕4
感谢。
答
这是一个内置的对象,完全是这样 - NSFetchedResultsController
。它被设计为与tableview或collectionView一起工作,但没有一个可以正常工作。它足够轻便,只用于一个物体是安全的。
答
感谢@jon,现在我的源代码已经大大改善。
class myBaseArrayController: NSArrayController, NSFetchedResultsControllerDelegate {
// https://developer.apple.com/documentation/coredata/nsfetchedresultscontroller
var frc: NSFetchedResultsController<NSManagedObject>?
func setupObserver() {
frc = NSFetchedResultsController(fetchRequest: defaultFetchRequest() as! NSFetchRequest<NSManagedObject>,
managedObjectContext: managedObjectContext!,
sectionNameKeyPath: nil, cacheName: nil)
frc?.delegate = self
do {
try frc?.performFetch()
}
catch {
fatalError("...")
}
}
}
其对应实体的每个ArrayController只是实现了controllerDidChangeContent()
。
class myOneOfThemArrayController: myBaseArrayController {
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
print("controllerDidChangeContent: \(controller.fetchRequest.entityName)")
// do some work
}
}
没有更多的比较,找到哪个是什么。 :-)
谢谢@jon,这就是我一直在寻找的! – Tora