问题描述:

I am using MagicalRecord to help with core data operation.

I have a NSOperation subclass called OfflineRetrieveOperation. It retrieve the message from the server and save it.

the code is like this:

NSManagedObjectContext *context = [NSManagedObjectContext contextForCurrentThread];

Message *existMessage = [Message MessageWithMessageID:messageID inManagedObjectContext:context];

if (!existMessage) {

Message *message = [Message insertMessageWithProperties:properties inManagedObjectContext:context];

}

[context save];

The notification receiver is initialized like this:

- (id)init

{

self = [super init];

if (self != nil) {

[[NSNotificationCenter defaultCenter] addObserver:self

selector:@selector(contextDidSave:)

name:NSManagedObjectContextDidSaveNotification

object:[NSManagedObjectContext defaultContext]];

[self setContext:[NSManagedObjectContext context]];

}

return self;

}

the log:

-[NSManagedObjectContext(MagicalRecord) saveWithErrorHandler:](0x5906a0) Saving Context

-[NSManagedObjectContext(MagicalRecord) mergeChangesFromNotification:](0x37eab0) Merging changes to *** DEFAULT *** context *** on Main Thread ***

Everything seems work fine except I can't receive the NSManagedObjectContextDidSaveNotification at all, so that I can't know that I have already finish retrieving.

网友答案:

Your OfflineRetrieveOperation is probably creating its own NSManagedObjectContext. When you save that context it will fire the NSManagedObjectContextDidSaveNotification. However you have an observer that will only listen for a NSNotification being broadcast by the [NSManagedObjectContext defaultContext].

Change your observer to consume notifications from your OfflineRetrieveOperation internal NSManagedObjectContext instead of [NSManagedObjectContext defaultContext] and it should start receiving them.

网友答案:

So, I'm guessing you probably want to update the objects in the defaultContext when you save them in the background context. MagicalRecord actually already handles that case for you when you create a new context using the helper method. That is, when you do something like this:

NSManagedObjectContext *backgroundOperationContext = 
          [NSManagedObjectContext contextThatNotifiesDefaultContextOnMainThread];

The context method has already setup the notifications necessary to tell the default context to merge the changes when it saves in the background. All you need to do is keep your context alive in the background operation and call save when you're ready to persist data.

Behind the scenes, the context method is doing exactly when Marcus is suggesting, and that is, adding a notification to the notification center:

[NSNotificationCenter defaultCenter] addObserver:[NSManagedObjectContext defaultContext]        
                                        selector:... 
                                            name:NSManagedObjectContextDidSaveNotification 
                                          object:backgroundOperationContext]

This isn't exactly the code, but this is pretty much what it does.

Bottom line, forget worrying about observing and merging changes from a background context to the default context yourself, MagicalRecord takes care of it for you.

相关阅读:
Top