Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Core data 在NSOperation子类中保存上下文时,无法接收NSManagedObjectContextDidSaveNotification_Core Data_Notifications_Nsoperation - Fatal编程技术网

Core data 在NSOperation子类中保存上下文时,无法接收NSManagedObjectContextDidSaveNotification

Core data 在NSOperation子类中保存上下文时,无法接收NSManagedObjectContextDidSaveNotification,core-data,notifications,nsoperation,Core Data,Notifications,Nsoperation,我用它来帮助核心数据操作 我有一个名为OfflineRetrieveOperation的NSOperation子类。它从服务器检索消息并保存它。 代码如下所示: NSManagedObjectContext *context = [NSManagedObjectContext contextForCurrentThread]; Message *existMessage = [Message MessageWithMessageID:messageID inManagedObjectContex

我用它来帮助核心数据操作

我有一个名为OfflineRetrieveOperation的NSOperation子类。它从服务器检索消息并保存它。 代码如下所示:

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的创造者肯定最有可能知道: