从属性中建立核心数据关系的最快方法是啥?
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 对象是通过引用而不是按值的结构。您只需将地址复制到字典中,因此内存开销非常小。 不在此示例中,但在我的真实应用中。以上是关于从属性中建立核心数据关系的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章