【发布时间】:2018-10-07 22:02:48
【问题描述】:
问题:更新和保存快,表之间的关系在两个或一个表已经保存后有大量数据。
我有五个表 TvGenres、TvSubgenre、TvProgram、Channels、TvSchedules,它们之间的关系如下图所示
现在的问题是所有数据下载都是根据以前的数据按顺序发生的,与 SQLite 不同,我需要设置它们之间的关系,为此我必须一次又一次地搜索表并设置它们之间的关系,即时间-消耗所以我怎样才能更快地做到这一点
我使用了 2 种不同的方法来解决,但都没有按预期工作
首先让我告诉你,下载是如何工作的
首先,我根据用户语言获取所有频道详细信息 从频道中,我获取下一周的所有时间表(这是很多数据(大约 30k+ )) 从时间表数据中,我获取所有程序数据(这又是很多数据)
方法一,
下载所有数据并创建它们的对象列表,然后在所有下载完成后立即存储它们,但仍然设置它们之间的关系需要时间,最糟糕的是,现在循环发生两次,首先我必须循环创建所有类列出然后再次循环以将它们存储在表格视图中,但仍然不能解决关系耗时问题。
方法 2
一一下载,就像下载频道存储它们然后下载时间表存储它们然后下载节目然后将它们存储在核心数据中这一切都可以,但是现在频道与时间表有关系,时间表与节目有关系并设置存储计划时的关系我还获取与该计划相关的频道,然后设置关系,对于程序和计划也是如此,下面是代码,所以我该如何解决这个问题或者我应该如何下载和存储它变成尽可能快。
仅用于存储计划的代码
func saveScheduleDataToCoreData(withScheduleList scheduleList: [[String : Any]], completionBlock: @escaping (_ programIds: [String]?) -> Void) {
let start = DispatchTime.now()
let context = coreDataStack.managedObjectContext
var progIds = [String]()
context.performAndWait {
var scheduleTable: TvSchedule!
for (index,response) in scheduleList.enumerated() {
let schedule: TvScheduleInformation = TvScheduleInformation(json: response )
scheduleTable = TvSchedule(context: context)
scheduleTable.channelId = schedule.channelId
scheduleTable.programId = schedule.programId
scheduleTable.startTime = schedule.startTime
scheduleTable.endTime = schedule.endTime
scheduleTable.day = schedule.day
scheduleTable.languageId = schedule.languageId
scheduleTable.isReminderSet = false
//if I comment out the below code then it reduce the time significantly from 5 min to 34.74 s
let tvChannelRequest: NSFetchRequest<Channels> = Channels.fetchRequest()
tvChannelRequest.predicate = NSPredicate(format: "channelId == %d", schedule.channelId)
tvChannelRequest.fetchLimit = 1
do {
let channelResult = try context.fetch(tvChannelRequest)
if channelResult.count == 1 {
let channelTable = channelResult[0]
scheduleTable.channel = channelTable
}
}
catch {
print("Error: \(error)")
}
progIds.append(String(schedule.programId))
//storeing after 1000 schedules
if index % 1000 == 0 {
print(index)
do {
try context.save()
} catch let error as NSError {
print("Error saving schdeules object context! \(error)")
}
}
}
}
let end = DispatchTime.now()
let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
print("Saving \(scheduleList.count) Schedules takes \(nanoTime) nano time")
coreDataStack.saveContext()
completionBlock(progIds)
}
还有如何使用自动释放池进行正确的批量保存
PS:我发现的所有与核心数据相关的材料都非常昂贵,成本超过 3k,而且免费提供的信息不多,只是基本的东西,即使苹果文档也没有太多与性能调整和批量更新相关的代码和交接关系。提前感谢您的帮助。
【问题讨论】:
-
你的谓词中应该有'==',而不是'='
-
我们是在谈论几 1000 条记录(节目、频道等)还是极少数(例如少于 100 条)您坚持的记录?
-
大约 7,000 多个频道,10,000 个时间表,大约 500 个频道,全部基于用户选择的语言,如果选择所有语言,则可能不止于此
-
"你的谓词中应该有 '==',而不是 '='" 实际上我虽然相同,但它的工作原理
-
@JoakimDanielson '=' 在谓词中是可以的。见Predicate Format String Syntax。
标签: swift loops core-data relationship nspredicate