工作时Xcode Core Data UI已锁定?

时间:2017-10-27 07:00:21

标签: ios xcode core-data

我正在尝试在我的应用程序核心数据中保存用户库歌曲,以便将它们与我的服务器同步。我的问题是:当用户有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()
          }
     } 

1 个答案:

答案 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*/
}