从CloudKit + CoreData触发了多个重复的NSPersistentStoreRemoteChange通知

问题描述

我看到.NSPersistentStoreRemoteChange条通知被多次接收,有时多达10次。

我不认为这是有害的,但是最好的情况是它会消耗处理能力。

所以我的问题是:

  • 这有害吗?
  • 我可以预防吗?
  • 如果不是,是否有建议的方法来忽略重复的通知?

-

我有以下代码来设置我的容器。这包含在一个单例的初始化程序中,我已经确认它被调用过一次。

guard let modelURL = Bundle(for: type(of: self)).url(forResource: momdName,withExtension:"momd"),let mom = NSManagedObjectModel(contentsOf: modelURL)
            else {
                fatalError("? Error loading model from bundle")
        }
        
        let containerURL = folderToStoreDatabaseIn.appendingPathComponent("Model.sqlite")
      
            container = NSPersistentCloudKitContainer(name: momdName,managedObjectModel: mom)
            
            guard let description = container.persistentStoreDescriptions.first else {
                fatalError("? ###\(#function): Failed to retrieve a persistent store description.")
            }
            
            description.url = containerURL
            description.setOption(true as NSNumber,forKey: NSPersistentHistoryTrackingKey)
            description.setOption(true as NSNumber,forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
              
        super.init()
        
            // this must be called after super.init()
            // ***** ADD OBSERVER *****
            NotificationCenter.default.addObserver(self,selector: #selector(updatedFromCKCD(_:)),name: .NSPersistentStoreRemoteChange,object: container.persistentStoreCoordinator)
        
        if let tokenData = try? Data(contentsOf: tokenFile) {
            do {
                lastToken = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSPersistentHistoryToken.self,from: tokenData)
            } catch {
                Logger.error("? ###\(#function): Failed to unarchive NSPersistentHistoryToken. Error = \(error)")
            }
        }

处理这些更改的代码:

// https://developer.apple.com/documentation/coredata/consuming_relevant_store_changes
    @objc func updatedFromCKCD(_ notifiction: Notification) {
        let fetchHistoryRequest = NSPersistentHistoryChangeRequest.fetchHistory(
            after: lastToken
        )
        
        let context = container.newBackgroundContext()
        guard
            let historyResult = try? context.execute(fetchHistoryRequest)
                as? NSPersistentHistoryResult,let history = historyResult.result as? [NSPersistentHistoryTransaction]
            else {
                Logger.error("⛈ Could not convert history result to transactions")
                assertionFailure()
                return
        }
        Logger.debug("⛈ Found cloud changes since: \(self.lastToken?.description ?? "nil")")
        
        DispatchQueue.main.async {
        // look for particular set of changes which require the user to take action
        ...
        }
    }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)