我正在尝试在我的应用程序核心数据中保存用户库歌曲,以便将它们与我的服务器同步。我的问题是:当用户有500多个曲目时,UI被锁定,直到核心数据循环检查完成!当CoreData正在进行大循环时,有没有办法避免UI锁定?比如像Android中的aSyncTask这样的后台无UI线程。
这是循环所在的代码。
/**
- Insert or Update tracks if exists in Database
- This function will "Not" run Sync with server once its done
*/
func insert_or_update_songs(tracks:[DTO_SONG],onComplete:(()->())!)
{
self.managedContext = APP_DELEGATE.managedObjectContext
var allTracks:[DTO_SONG] = tracks
var track_with_ddID:[DTO_SONG] = []
var sid:[String] = []
var dd_song_ids:[Int32] = []
var allObjects:[Song_Entity] = []
//Get Tracks ID's to see if they already in DB
if allTracks.count > 0
{
for track in tracks
{
//if Track has dd id ?
if track.dd_song_id > 0
{
track_with_ddID.append(track)
dd_song_ids.append(Int32(track.dd_song_id))
}else
//Match by Hash
{
sid.append( ddTools().md5("\(track.song_name)\(track.artist_name)") )
}
}
//[UPDATE] by HASH Now Fetch All found in DB
if sid.count > 0
{
self.log("[HASH] Match by HASH : \(sid.count)")
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Song_Entity")
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [NSPredicate(format:"sid IN %@", sid)])
do{
if try self.managedContext.count(for:request) > 0
{
if let _tracks:[Song_Entity] = try self.managedContext.fetch(request) as? [Song_Entity]
{
allObjects += _tracks
// for track in _tracks
// {
// //Remove from Array
// if let i = allTracks.index(where: { ddTools().md5("\($0.song_name)\($0.artist_name)") == track.sid })
// {
// //Update track info
// //self.update_track(allTracks[i],track)
// //Now remove
// self.log("[HASH] Removed Already exists : \(allTracks[i].song_name)")
// allTracks.remove(at: i)
// }
// }
}
}
}catch let error as NSError { self.log("[HASH] Error while checking Tracks : \(error), \(error.userInfo)") }
}
//[UPDATE] by ID Now Fetch All found in DB
if dd_song_ids.count > 0
{
self.log("[ID] Match by dd ID : \(sid.count)")
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Song_Entity")
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [NSPredicate(format:"dd_song_id IN %@", dd_song_ids)])
do{
if try self.managedContext.count(for:request) > 0
{
if let _tracks:[Song_Entity] = try self.managedContext.fetch(request) as? [Song_Entity]
{
allObjects += _tracks
// for track in _tracks
// {
// //Remove from Array
// if let i = allTracks.index(where: { $0.dd_song_id == track.dd_song_id })
// {
// //Update track info
// //self.update_track(allTracks[i],track)
// //Now Remove
// self.log("[ID] Removed Already exists : \(allTracks[i].song_name)")
// allTracks.remove(at: i)
// }
// }
}
}
}catch let error as NSError { self.log("[ID] Error while checking Tracks : \(error), \(error.userInfo)") }
}
}
self.log("[NEW] Tracks to check and insert \(allTracks.count) , check with \(allObjects.count) Tracks ")
for track in allTracks
{
//if not in there this insert it
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)
}
}
dd_song_ids.removeAll()
sid.removeAll()
track_with_ddID.removeAll()
allTracks.removeAll()
allObjects.removeAll()
//save changed
if self.managedContext.hasChanges
{
do {
try self.managedContext.save()
self.log(" New Changes has been Saved.")
} catch let error as NSError { self.log(" Could not save. \(error), \(error.userInfo)") }
}
//Sync with Server
if onComplete != nil
{
onComplete()
}
}
答案 0 :(得分:1)
您使用dispatch_async并在iOS中阻止:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
// in half a second...
print("Are we there yet?") // add coreData loop
}
或者像主队列一样异步使用
DispatchQueue.main.async
{
/*Write your thread code here*/
}