开发者

NSManagedObject: create on separate thread

开发者 https://www.devze.com 2023-03-18 06:03 出处:网络
I understand that Core Data is not thread safe and that NSManagedObjectContext and NSManagedObjects associated with a context cannot be passed from thread to thread.

I understand that Core Data is not thread safe and that NSManagedObjectContext and NSManagedObjects associated with a context cannot be passed from thread to thread.

Question:

However, if I have a NSManagedObjectContext on my main thread, can I create a NSManagedObject object on a background thread (WITHOUT attaching it to any context -- that is, simply call alloc/init on NSManagedObject), then pass that NSManagedObject back to the main thread and add it to the context from there? I've reviewed the docs on Core Data concurrency, but can't find an开发者_Python百科ything that says this usage pattern is okay.

Context:

I have a background thread that performs a complex task and then publishes a result. The result is an NSManagedObject subclass that contains a few attributes: time, a file path, and a success or error message (as a string). I want to create the result object on the background thread, then toss it back to the main thread and add it to the Core Data context where it will be displayed in a tableView.

If I can't create the managedObject on the background thread, then I'll need to create a dictionary, pass the dictionary to the main thread, read the keys, create the managedObject from those values, etc. Just seems cleaner to create the managedObject on the background thread if possible.


The better approach is to have a context per thread. This way each thread will have its own scratch pad to play around with. Then when you background thread finishes, tell your main thread to update its view or ui table view or how every you are presenting your data.

You'll need to notify your main thread when changes occur. The big problem is, the contexts between different threads and main thread are not aware of each other. There is a way in core data to keep the contexts in sync. When you want to save, the context on the background thread should broadcast an NSManagedObjectContextDidSaveNotification notification.

So for example, in your main method in your NSOperation, you could do this:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
[nc addObserver:self
       selector:@selector(mergeChanges:)
           name:NSManagedObjectContextDidSaveNotification
         object:context];

the mergeChanges would be a private method in your NSOperation instance.

example of merge changes

- (void)mergeChanges:(NSNotification *)notification
{
    ApplicationController *appController = [[NSApplication sharedApplication] delegate];
    NSManagedObjectContext *mainContext = [appController managedObjectContext];

    // Merge changes into the main context on the main thread
    [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                                  withObject:notification
                               waitUntilDone:YES];  
}
0

精彩评论

暂无评论...
验证码 换一张
取 消