我试图编辑/插入CoreData对象,我在做什么是这样的:Xcode DispatchQueue.main.async内部或外部大循环?
DispatchQueue.main.async {
for track in allTracks
{
if let i = allObjects.index(where: { $0.sid == ddTools().md5("\(track.song_name)\(track.artist_name)") })
{
self.log("[NEW][\(i)] Already in DB : \(track.song_name)")
}else
{
self.insert_track(track)
}
}
}
,但它仍然阻塞UI,如果阵列有超过500多个对象,它是安全的,如果我这样做呢?
for track in allTracks
{
DispatchQueue.main.async {
if let i = allObjects.index(where: { $0.sid == ddTools().md5("\(track.song_name)\(track.artist_name)") })
{
self.log("[NEW][\(i)] Already in DB : \(track.song_name)")
}else
{
self.insert_track(track)
}
}
}
我可以在循环的CoreData对象内使用DispatchQueue.main.async!排尿阻塞UI
一些建议后,我也有功能更新,这
func insert_or_update_songs(tracks:[DTO_SONG],onComplete:(()->())!)
{
let allTasksGroup = DispatchGroup()
var totalFinished:Int = 0
for track in tracks
{
DispatchQueue.main.async
{
allTasksGroup.enter()
//Fetch if Exists
let context = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext
let songHash = ddTools().md5("\(track.song_name)\(track.artist_name)")
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Song_Entity")
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [NSPredicate(format:"sid = %@", songHash),
NSPredicate(format:"sid != %@", "")])
do{
if try context.count(for:request) > 0
{
//Update the Track
if let _tracks:[Song_Entity] = try context.fetch(request) as? [Song_Entity]
{
self.update_track(track, _tracks[0])
}
}else
//Insert as new track
{
self.insert_track(track,context :context)
}
if context.hasChanges
{
do {
try context.save()
self.log(" New Changes has been Saved.")
} catch let error as NSError { self.log(" Could not save. \(error), \(error.userInfo)") }
}
totalFinished += 1
print(" \(totalFinished)/\(tracks.count)")
allTasksGroup.leave()
}catch let error as NSError { self.log("[HASH] Error while checking Track if in DB: \(error), \(error.userInfo)") }
}
}
//When all done
allTasksGroup.notify(queue: .main) {
self.log("[INSERT OR UPDATE BATCH] Total Finished : \(totalFinished)/\(tracks.count) ")
if totalFinished == tracks.count
{
if onComplete != nil
{
onComplete()
}
}
}
allTracks不coredata对象,allObjects是。所以你的意思是我必须循环所有曲目,并在循环内使coredata获取并保存每个曲目? – Jack
那么你无法访问主线程上的所有对象。但它是一样的想法。我没有看到您的代码中的任何地方正在写入核心数据。 –
我已经更新了问题和函数后,你的意见,与coredata – Jack