Bre*_*ley 2 core-data ios swift
我正在开发一个定期从服务器下载数据的应用程序.如果数据需要更新,我会使用类似的内容来更新记录或插入新记录(如果它们不存在).
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Trip")
for csvTrip in csvTrips {
var trip: NSManagedObject!
let tripId = Int(csvTrip[0])!
fetchRequest.predicate = NSPredicate(format: "id = %d", tripId)
if (context.count(for: fetch) == 0) {
trip = NSEntityDescription.insertNewObject(forEntityName: "Trip", into: context)
trip.setValue(tripId, forKey: "id")
} else {
tripObject = (context.fetch(fetch) as! [NSManagedObject])[0]
}
// Set other properties
}
Run Code Online (Sandbox Code Playgroud)
检查实体是否已存在于每个循环中使得它比仅插入它们大约慢100倍而不进行检查,这对于超过几千个实体来说变成了一个大问题.我已经尝试首先获取所有实体,但我仍然必须循环遍历每个实体并将id添加到数组或其他东西,这不是更快.我知道核心数据与MySQL不同,但我很难相信没有类似INSERT ...... ON DUPLICATE KEY UPDATE的功能,这在MYSQL中非常快.我错过了什么吗?
Lio*_*ion 12
您可以使用 Core Data独特的约束技术。
loadPersistentStores()方法调用以允许 Core Data 更新您的对象:container.loadPersistentStores { storeDescription, error in
self.container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
if let error = error {
print("Unresolved error \(error)")
}
}
Run Code Online (Sandbox Code Playgroud)
注意:使用属性约束可能会导致问题NSFetchedResultsController:属性约束仅在保存时强制执行为唯一,这意味着如果您要插入数据,则NSFetchedResultsController在保存之前可能会包含重复项。您可以通过在加载之前执行保存来避免这种情况。只需要知道,做出这样的改变取决于你。
您可以在此处阅读有关此技术的更多信息。
如果取出几千个实体并将ID加载到Set一个特定的很长时间,我会感到惊讶.
你可以使用类似的东西:
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Trip")
fetchRequest.resultType = .dictionaryResultType
fetchRequest.propertiesToFetch = ["id"]
do {
if let results = try self.moc.fetch(fetchRequest) as? [[String:Any]] {
let idSet = Set<Int32>(results.flatMap({ (dict) -> Int32? in
return dict["id"] as? Int32
}))
}
} catch {
print("Error reading trips")
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以轻松检查给定的ID是否是新的,并在需要时插入新的行程:
for csvTrip in csvTrips {
if let tripId = Int(csvTrip[0]) {
if !idSet.contains(tripId) {
trip = NSEntityDescription.insertNewObject(forEntityName: "Trip", into: context)
trip.setValue(tripId, forKey: "id")
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中,这需要1.35秒来将320,000次行程ID加载到一个集合中,并且需要0.08秒来创建10,000次新行程,同时检查行程ID是否包含在集合中.
| 归档时间: |
|
| 查看次数: |
1686 次 |
| 最近记录: |