【问题标题】:Unique Constraints do not work唯一约束不起作用
【发布时间】:2017-03-26 08:26:27
【问题描述】:

我正在使用 ios 10、xcode 8(如果这很重要,只需提及所有内容)。所以根据 wwmd 的说法,不需要 fetch 请求来检查核心数据中是否有东西,如果是,则不保存,以免重复。已经为此引入了独特的约束。所以我有一个名为 List 的实体,以 id 作为属性。在约束条件下,我列出了 id (正如 wwmd 上的演示者所做的那样)。我还给出了我正在使用NSMergeByPropertyObjectTrumpMergePolicy 合并策略的上下文。

var context: NSManagedObjectContext {
    mutating get {
        if #available(iOS 10.0, *) {
            let context = persistentContainer.viewContext
            context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
            return context
        } else {
            return managedObjectContext
        }
    }

}

在我看来,它不起作用。我可以保存相同的ID,它会重复!!!。并且绝对没有与 IOS 10 相关的文档。我使用 swift IO9 managedObjectContext 使其工作,但不能使其与 IOS10 persistentcontainer.viewcontext 一起工作。如果有人对此有解决方案,将不胜感激。

【问题讨论】:

    标签: swift core-data ios10


    【解决方案1】:

    解决方案:我在需要上下文的视图控制器中添加了视图 didload 中的合并策略。 更新:更好的解决方案:由于核心数据的独特约束不适用于关系,我最终使用了核心存储,它具有出色的唯一性算法以及许多有用的核心数据包装器。

    【讨论】:

      【解决方案2】:

      唯一约束仅在您保存上下文时起作用。

      创建 NSMangaedObjects 后,保存创建它们的 NSManagedContext。

      是的,如果您的实体中有关系,则唯一约束不起作用。(我在 xcode 7.3 ios9 上尝试过)

      【讨论】:

      • 是的,我有唯一约束,我在 for 循环 MangedObject(context: context) 中创建新对象,然后通过 addToResults() 之类的关系添加它,唯一约束根本不起作用。这很奇怪,但我以重复结束
      【解决方案3】:

      我正在使用这样的东西来避免重复,使用唯一约束在通过关系 addToXXX() 方法添加托管对象时不起作用

       let ids = e.results.map { $0._identifier }
              let request = MovieObject.fetchRequest()
              request.predicate = NSPredicate(format: "id in %@", ids)
      
              let existing = (try? request.execute() as? [MovieObject]) ?? []
      
              let toUpdate = e.results.filter {
                  existing.map { $0.id }.contains($0._identifier)
              }.map { movie in
                  (movie, existing.first(where: { $0.id == movie._identifier })!)
              }
      
              let toInsert = e.results.filter {
                  !existing.map { $0.id }.contains($0._identifier)
              }
      
              toInsert.forEach { movie in
                  let o = MovieObject(context: self.managedObjectContext!)
                  o.encode(entity: movie)
                  self.addToResults(o)
              }
      
              toUpdate.forEach {
                  let (m, o) = $0
                  o.encode(entity: m)
                  self.addToResults(o)
              }
      

      【讨论】:

        猜你喜欢
        • 2013-01-18
        • 1970-01-01
        • 2017-11-18
        • 1970-01-01
        • 2011-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多