英文:
How do I loop through all open background view contexts and perform a save?
问题
我有一个程序,同时从3个不同的CSV文件中并发读取数据,将它们加载到3个不同的后台视图上下文中,这些上下文都基于相同的持久容器。一旦数据已插入到视图上下文中,我使用一系列if
语句来测试是否已进行更改,如果有更改,则保存视图上下文到共同的持久存储。程序可以正常工作。但我觉得我应该能够查询核心数据以获取这些视图上下文的列表,然后依次循环遍历它们并执行保存,以简化代码。不幸的是,我一直无法确定如何做到这一点。以下是我的代码子集,这些代码都包含在同一个视图模型类中。
let BGContext1 = persistentContainer.newBackgroundContext()
let BGContext2 = persistentContainer.newBackgroundContext()
let BGContext3 = persistentContainer.newBackgroundContext()
... 通过withTaskGroup加载视图上下文的数据的代码
if BGContext1.hasChanges {
do {
try BGContext1.save()
} catch {
print("error saving \(error)")
}
}
if BGContext2.hasChanges {
do {
try BGContext2.save()
} catch {
print("error saving \(error)")
}
}
if BGContext3.hasChanges {
do {
try BGContext3.save()
} catch {
print("error saving \(error)")
}
}
如果可能的话,我想要翻译的代码已经翻译好了。
英文:
I have a program that concurrently reads the data from 3 separate CSV files into 3 separate background view contexts all based on the same persistent container. Once the data has been inserted into the view contexts I use a series of if
statements to test if changes have been made, and if so, save the view contexts to the common persistent store. The program works. But it seems to me that I should be able to query core data for a listing of these view contexts and then in turn loop through them and perform the save, simplifying the code. Unfortunately I have been unable to determine how to do it. Below is a subset of my code which is all contained within the same view model class.
let BGContext1 = persistentContainer.newBackgroundContext()
let BGContext2 = persistentContainer.newBackgroundContext()
let BGContext3 = persistentContainer.newBackgroundContext()
... code that loads view contexts with data via withTaskGroup
if BGContext1.hasChanges {
do {
try BGContext1.save()
} catch {
print("error saving \(error)")
}
}
if BGContext2.hasChanges {
do {
try BGContext2.save()
} catch {
print("error saving \(error)")
}
}
if BGContext3.hasChanges {
do {
try BGContext3.save()
} catch {
print("error saving \(error)")
}
}
答案1
得分: 1
Larme是正确的。将保存功能放入我的解析函数中有效。从那时起,我了解到可以将CSV数据直接保存到Core Data,即一个带有批量插入的SQLite文件。下面是执行批量插入的函数。这样就不必在视图上下文上执行保存操作,而且速度非常快。
func CSVtoCoreData(latestDate: Date, bgContext: NSManagedObjectContext) async {
bgContext.performAndWait {
var arrayOfDict: [[String:Any]] = []
var data: String = ""
do {
data = try String(contentsOfFile: filePath)
} catch {
print(error)
return
}
var rows = data.components(separatedBy: "\n")
rows.removeFirst()
for row in rows {
let columns = row.components(separatedBy: ",")
let tempDate = columns[0].replacingOccurrences(of: "/", with: "")
let tempTimeStamp = stringToDateFormatterWSJ.date(from: tempDate)!
let close = Float(columns[4].replacingOccurrences(of: " ", with: ""))!
let newRecord: [String:Any] = [
"fundName": fundName,
"id": UUID(),
"timeStamp": tempTimeStamp,
"close": close
]
arrayOfDict.append(newRecord)
}
let insertRequest = NSBatchInsertRequest(entity: TradingDayClose.entity(), objects: arrayOfDict)
bgContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
_ = try? bgContext.execute(insertRequest) as? NSBatchInsertResult
}
}
请注意,我已经去掉了HTML实体字符(如")以使代码正常显示。
英文:
Larme is correct. Putting the save functionality into my parsing function works. Since then, I learned that you can save the CSV data directly into Core Data i.e. an SQLite file with a batch insert. Below is the function that performs the batch insert. This eliminates having to perform a save on the view contexts and its is very fast.
func CSVtoCoreData(latestDate: Date, bgContext: NSManagedObjectContext) async {
bgContext.performAndWait {
var arrayOfDict: [[String:Any]] = []
var data: String = ""
do {
data = try String(contentsOfFile: filePath)
} catch {
print(error)
return
}
var rows = data.components(separatedBy: "\n")
rows.removeFirst()
for row in rows {
let columns = row.components(separatedBy: ",")
let tempDate = columns[0].replacingOccurrences(of: "/", with: "")
let tempTimeStamp = stringToDateFormatterWSJ.date(from: tempDate)!
let close = Float(columns[4].replacingOccurrences(of: " ", with: ""))!
let newRecord: [String:Any] = [
"fundName": fundName,
"id": UUID(),
"timeStamp": tempTimeStamp,
"close": close
]
arrayOfDict.append(newRecord)
}
let insertRequest = NSBatchInsertRequest(entity: TradingDayClose.entity(), objects: arrayOfDict)
bgContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
_ = try? bgContext.execute(insertRequest) as? NSBatchInsertResult
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论