从属性中建立核心数据关系的最快方法是啥?

Posted

技术标签:

【中文标题】从属性中建立核心数据关系的最快方法是啥?【英文标题】:How is the fastest way to make relation in core data from a attribute?从属性中建立核心数据关系的最快方法是什么? 【发布时间】:2018-04-20 19:43:17 【问题描述】:

我正在对同步算法进行性能优化。

目前,ios 应用从 Web API 接收大量 JSON。 在许多情况下,存在与关系相关的属性,例如: PS。这是一个简化的例子。

[
    
        "name":"Alice",
        "age": 18,
        "key": "a001"
    ,
    
        "name":"Bob",
        "age": 18,
        "key": "b002",
        "parent":"a001"
    ,
]

给定 CoreData 中的模型:

下载 JSON 后,我需要将其保存到 Core Data 中。但是,我需要建立这些对象之间的关系。

目前,我正在coredata上搜索对象并建立关系,您如何在下面的示例中看到(PS。这是一个简化的示例):

@IBAction func newItemTap(_ sender: Any) 

    if let context = self.managedObjectContext 
        let newPerson = Person(context: context)
        newPerson.name = "Alice"
        newPerson.age = 18
        newPerson.key = "a001"
    



@IBAction func secondItemTap(_ sender: Any) 
    if let context = self.managedObjectContext 

        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Person")
        fetchRequest.fetchLimit = 1
        fetchRequest.predicate = NSPredicate(format: "key = %@", "a001")
        do 
            if let results = try context.fetch(fetchRequest) as? [NSManagedObject] 
                if results.count > 0 
                    let newPerson = Person(context: context)
                    newPerson.name = "Bob"
                    newPerson.age = 18
                    newPerson.key = "b002"
                    newPerson.parent = results.first as! Person?
                
            
         catch 
            print("Error reading trips")
        
    

@IBAction func checkTap(_ sender: Any) 
    if let context = self.managedObjectContext 

        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Person")
        do 
            if let results = try context.fetch(fetchRequest) as? [Person] 
                for obj: Person in results 
                    print(obj.name ?? "")
                    print(obj.parent?.name ?? "<no parent>")
                
            
         catch 
            print("Error reading trips")
        
    

我正在寻找一种快速建立关系的方法,如 secondItemTap 方法所示。

有人遇到并解决过这种性能问题吗?有什么建议吗?

【问题讨论】:

【参考方案1】:

我不是很精通CoreData,所以我不能提供实际代码,但基本上可以归结为以下几点:

确保您的数据库在您的 key 属性上维护一个良好的索引。

根据您的数据库,在CoreData 中定义它可能有不同的方法,但从this question 来看,它似乎真的可以归结为只需在数据定义的indexed 属性上打勾(即非常接近应有的样子)。

【讨论】:

这不是重点。索引已优化。我正在寻找一个好的策略来做到这一点。 如果您的索引类似于“优化”,我看不到 secondItemTap 很慢。但是,这可能取决于您的数据库,但是像本地 SQLite 这样的东西应该很容易满足您的需求(假设它们在 100 毫秒范围内,这对于轻按来说似乎是合理的)。如果您还有其他问题,您应该更具体地了解它们。【参考方案2】:

据我了解,您希望优化同一操作的速度,并且您担心每次从上下文中获取都非常耗时。这可以通过自己对信息进行索引来解决。

假设您的 CoreData 中没有 json 的副本,那么您必须创建每个托管对象并将其注入到上下文中,为了避免以后搜索它,您可以保留一个类型的字典:

[String: ManagedObject]

并将所有注入的对象保留在那里。由于您只保留对这些管理对象的引用,因此内存开销很小。

在第一轮中,您创建所有对象,并在我们上面提到的类型的字典中保留一份副本。

在第二轮中,您遍历字典并建立关系。

如果您的代码数据中已经有一个 json 副本,并且想用这个大的 json 更新它,那么您需要从核心数据中获取数据然后更新它。

【讨论】:

我已经在字典中使用了这个策略。但是它分配了太多的内存。 不,它没有,字典持有对托管对象的引用,而不是复制整个对象,请记住,swift 对象是通过引用而不是按值的结构。您只需将地址复制到字典中,因此内存开销非常小。 不在此示例中,但在我的真实应用中。

以上是关于从属性中建立核心数据关系的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

排序和过滤核心数据关系的更有效方法是啥?

创建核心数据模型设计的最佳方法是啥?

核心数据关系的性能改进

不同实体核心数据属性的最大值

如何在 iOS 中建立多对多关系? (核心数据)

使用核心数据在 ios 中建立一对多关系