Luca Davanzo
Luca Davanzo

Reputation: 21528

Core data: load data in background and save

I need to load a lot of data from a csv.
To avoid UI freeze I have to do this on a different thread.

@objc(Person)
class Person: NSManagedObject {
    @NSManaged var name: String?
}

func createDummies(completion : (success : Bool, result: [Person]?, error : NSError?) -> Void) {
    let qualityOfServiceClass = QOS_CLASS_BACKGROUND
    let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
    dispatch_async(backgroundQueue, { () -> Void in
       var res: [Person] = []
       for var i = 0; i < 10; ++i {
          let p = Person.MR_CreateEntity
          res.append(p)
       }
       completion(success: true, result: p, error: nil)
    })        
}

func loadDummies() {
   createDummies({ (success, result, error) -> Void in
      MagicalRecord.saveWithBlock { (m: NSManagedObjectContext!) -> Void in
         let persons = Person.MR_findAll() as? [Person]
         println("block \(persons)")
      }
      let persons = Person.MR_findAll() as? [Person]
      println("out block \(persons)")

   } 
}

This code produce a strange output:

 block Optional([])
 out block Optional([ <Person: 0x7fd0224129e0> (entity: Person;] ..... etc)

So, if after this I call Person.MR_FindAll in another view controller, result is an empty array.

Any ideas? I think the problem is creating and saving entities in different thread: if is this the case, how can I workaround this problem?

Upvotes: 0

Views: 99

Answers (1)

Hashmat Khalil
Hashmat Khalil

Reputation: 1816

Core Data objects are not thread-safe! and you should not definitely do huge update / save on the main context of you core data it will freeze your UI. if you are using child-parent context method with NSFetchResultController delegates then your data on the UI will be updated automatically if your background context is child of UI context. the UI context should be of type NSMainQueueConcurrencyType and the child(background) context should be of type NSPrivateQueueConcurrencyType.the NSManagedObjectContext has performBlockAndWait and performBlock methods where you should perform fetch and update.

Upvotes: 1

Related Questions