如何注意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一起工作,但没有一个可以正常工作。它足够轻便,只用于一个物体是安全的。

+0

谢谢@jon,这就是我一直在寻找的! – Tora

感谢@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 
    } 

} 

没有更多的比较,找到哪个是什么。 :-)