Core data 在NSOperation子类中保存上下文时,无法接收NSManagedObjectContextDidSaveNotification
我用它来帮助核心数据操作 我有一个名为OfflineRetrieveOperation的NSOperation子类。它从服务器检索消息并保存它。 代码如下所示:Core data 在NSOperation子类中保存上下文时,无法接收NSManagedObjectContextDidSaveNotification,core-data,notifications,nsoperation,Core Data,Notifications,Nsoperation,我用它来帮助核心数据操作 我有一个名为OfflineRetrieveOperation的NSOperation子类。它从服务器检索消息并保存它。 代码如下所示: NSManagedObjectContext *context = [NSManagedObjectContext contextForCurrentThread]; Message *existMessage = [Message MessageWithMessageID:messageID inManagedObjectContex
NSManagedObjectContext *context = [NSManagedObjectContext contextForCurrentThread];
Message *existMessage = [Message MessageWithMessageID:messageID inManagedObjectContext:context];
if (!existMessage) {
Message *message = [Message insertMessageWithProperties:properties inManagedObjectContext:context];
}
[context save];
- (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;
}
NSManagedObjectContext *backgroundOperationContext =
[NSManagedObjectContext contextThatNotifiesDefaultContextOnMainThread];
通知接收器的初始化方式如下:
NSManagedObjectContext *context = [NSManagedObjectContext contextForCurrentThread];
Message *existMessage = [Message MessageWithMessageID:messageID inManagedObjectContext:context];
if (!existMessage) {
Message *message = [Message insertMessageWithProperties:properties inManagedObjectContext:context];
}
[context save];
- (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;
}
NSManagedObjectContext *backgroundOperationContext =
[NSManagedObjectContext contextThatNotifiesDefaultContextOnMainThread];
日志:
-[NSManagedObjectContext(MagicalRecord) saveWithErrorHandler:](0x5906a0) Saving Context
-[NSManagedObjectContext(MagicalRecord) mergeChangesFromNotification:](0x37eab0) Merging changes to *** DEFAULT *** context *** on Main Thread ***
一切似乎都正常,只是我根本无法接收NSManagedObjectContextDidSave通知,因此我无法知道我已完成检索。您的离线检索操作可能正在创建自己的NSManagedObjectContext。保存该上下文时,它将触发NSManagedObjectContextDidSaveNotification。但是,您有一个观察者,它将只侦听[NSManagedObjectContext defaultContext]正在广播的NSNotification
将您的观察者更改为使用来自OfflineRetrieveOperation内部NSManagedObjectContext而不是[NSManagedObjectContext defaultContext]的通知,它应该开始接收通知。您的OfflineRetrieveOperation可能正在创建自己的NSManagedObjectContext。保存该上下文时,它将触发NSManagedObjectContextDidSaveNotification。但是,您有一个观察者,它将只侦听[NSManagedObjectContext defaultContext]正在广播的NSNotification
将您的观察者更改为使用脱机检索操作内部NSManagedObjectContext而不是[NSManagedObjectContext defaultContext]中的通知,它将开始接收通知。因此,我猜您可能希望在后台上下文中保存时更新defaultContext中的对象。当您使用helper方法创建新上下文时,MagicalRecord实际上已经为您处理了这种情况。也就是说,当你这样做的时候:
NSManagedObjectContext *context = [NSManagedObjectContext contextForCurrentThread];
Message *existMessage = [Message MessageWithMessageID:messageID inManagedObjectContext:context];
if (!existMessage) {
Message *message = [Message insertMessageWithProperties:properties inManagedObjectContext:context];
}
[context save];
- (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;
}
NSManagedObjectContext *backgroundOperationContext =
[NSManagedObjectContext contextThatNotifiesDefaultContextOnMainThread];
context方法已经设置了必要的通知,以告知默认上下文在后台保存时合并更改。您只需在后台操作中保持上下文的活动状态,并在准备持久化数据时调用save
在幕后,上下文方法正是在Marcus建议的时候进行的,也就是说,向通知中心添加通知:
[NSNotificationCenter defaultCenter] addObserver:[NSManagedObjectContext defaultContext]
selector:...
name:NSManagedObjectContextDidSaveNotification
object:backgroundOperationContext]
这不完全是代码,但它基本上就是这么做的
总之,不要担心自己观察和合并从背景上下文到默认上下文的更改,MagicalRecord会为您处理这些更改。因此,我猜您可能希望在将对象保存到背景上下文时更新defaultContext中的对象。当您使用helper方法创建新上下文时,MagicalRecord实际上已经为您处理了这种情况。也就是说,当你这样做的时候:
NSManagedObjectContext *context = [NSManagedObjectContext contextForCurrentThread];
Message *existMessage = [Message MessageWithMessageID:messageID inManagedObjectContext:context];
if (!existMessage) {
Message *message = [Message insertMessageWithProperties:properties inManagedObjectContext:context];
}
[context save];
- (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;
}
NSManagedObjectContext *backgroundOperationContext =
[NSManagedObjectContext contextThatNotifiesDefaultContextOnMainThread];
context方法已经设置了必要的通知,以告知默认上下文在后台保存时合并更改。您只需在后台操作中保持上下文的活动状态,并在准备持久化数据时调用save
在幕后,上下文方法正是在Marcus建议的时候进行的,也就是说,向通知中心添加通知:
[NSNotificationCenter defaultCenter] addObserver:[NSManagedObjectContext defaultContext]
selector:...
name:NSManagedObjectContextDidSaveNotification
object:backgroundOperationContext]
这不完全是代码,但它基本上就是这么做的
总之,不要担心观察和合并从背景上下文到默认上下文的更改,MagicalRecord会为您处理这些更改。谢谢您,Marcus。我尝试在不同的线程中执行所有类型的操作,然后将更改合并到[NSManagedObjectContext defaultContext]。广播通知的是操作的NSManagedObjectContext。您需要将addNotification的对象设置为广播公司,或设置为nil以接收通知。我建议阅读NSNotification和NSNotificationCenter的工作原理。由于有不同类型的操作可能会更改数据,因此通知接收者只关心defaultContext会很方便。我想我可以这样做:[[OfflineRetrieveOperationContext]保存];[[NSManagedObjectContext defaultContext]保存];第二次保存将触发NSManagedObjectContextDidSaveNotification,通知接收者将收到此消息。如果[notification userInfo]没有内容,请使用NSFetchedResultsController执行蚀刻并获取最新数据。否。只有操作的上下文才会触发通知,因为它是唯一有更改的上下文。时期您必须侦听操作上下文或nil才能使其工作。我已尝试过。第二次保存确实触发了NSManagedObjectContextDidSaveNotification,[notification userInfo]为空:{inserted={\n};updated={\n};}谢谢你,Marcus。我尝试在不同的线程中执行所有类型的操作,然后将更改合并到[NSManagedObjectContext defaultContext]。广播通知的是操作的NSManagedObjectContext。你
需要设置对象:将addNotification发送给广播公司或设置为nil以接收通知。我建议阅读NSNotification和NSNotificationCenter的工作原理。由于有不同类型的操作可能会更改数据,因此通知接收者只关心defaultContext会很方便。我想我可以这样做:[[OfflineRetrieveOperationContext]保存];[[NSManagedObjectContext defaultContext]保存];第二次保存将触发NSManagedObjectContextDidSaveNotification,通知接收者将收到此消息。如果[notification userInfo]没有内容,请使用NSFetchedResultsController执行蚀刻并获取最新数据。否。只有操作的上下文才会触发通知,因为它是唯一有更改的上下文。时期您必须侦听操作上下文或nil才能使其工作。我已尝试过。第二次保存确实触发了NSManagedObjectContextDidSaveNotification,[notification userInfo]为空:{inserted={\n};updated={\n};}+1 MagicalRecord的创建者很可能知道:+1 MagicalRecord的创造者肯定最有可能知道: