What would be a thread-safe way to save a context form Core Data?

耗尽温柔 提交于 2019-12-11 12:47:14

问题


I have a NSOperationQueue set to NSOperationQueueDefaultMaxConcurrentOperationCount. It is filled with NSOperation objects (nothing weird so far). I subclassed the NSOperation to do some background tasks.

  1. Download data from the internet.
  2. Parse the data so I can read it.
  3. Create a NSManagedObject:

    [NSEntityDescription insertNewObjectForEntityForName:@"Channel" inManagedObjectContext:context];

  4. Save it with the context.

    [managedObjectContext save:&error]

I like this all to happen in the background so the UI won't get blocked. I read this article about concurrency with core data, and as far as I understood it. The best way would be to create a new NSManagedObjectContext in every NSOperation, but share the same persistent store coordinator.

That's easily done, however, when it comes to saving the context it says in the documentation it is error prone to do so. So my question is the following:

  1. If I have different operations running in the NSOperationQueue, could those operations interfere with each other while saving the managed object context? Or does it wait to execute the following operation till the saving has been complete?

  2. Can I safely save the context in a NSOperation? Or is it really bad practice?

I hope someone can shine a light on this matter, because I am really stuck at the moment.


回答1:


What you need to do is the following:

  1. Create a managed object context for each NSOperation. Create this new context on the main method, because this is when it's executing on the right thread.
  2. Assign the context persistent store coordinator.
  3. Create an observer to receive the NSManagedObjectContextDidSaveNotification. This is the only way the main context will know at the time the changes were made on the NSOperation's context. Make sure the merge call is made on the thread/block the merging context lives in. If you are merging with the main thread's context, call the mergeChangesFromContextDidSaveNotification: method on the main thread with the notification from the NSOperation's context.

Also, ask yourself if you really want to have all these operations working concurrently. Per the documentation:

The default maximum number of operations is determined dynamically by the NSOperationQueue object based on current system conditions.

You do not have control over how many NSOperations will be operating at the same time. If this is not what you want, you might be better if you just go with a serial NSOperationQueue (maxConcurrentOperation=1), considering the fact that you are going to be locking the database to do the save, and also because you have networking being done as well.

You can safely save inside the NSOperation's main method, if you take the precautions mentioned above.



来源:https://stackoverflow.com/questions/11924912/what-would-be-a-thread-safe-way-to-save-a-context-form-core-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!