我試圖編輯/插入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