0
-(void)someBackgroundTask {
   NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
   [context setPersistentStoreCoordinator:[self coordinator]];

   // ...

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

   [context save:&error];

   // safe?
   [notificationCenter removeObserver:self name:NSManagedObjectContextDidSaveNotification object:context];

   // ...
}


// meanwhile on the main thread...
-(void)handleSaveNotification:(NSNotification *)notification {
   [[self context] mergeChangesFromContextDidSaveNotification:notification];
}

在调用 to 之后这么快就移除观察者是否安全save:

4

1 回答 1

1

只要您收到了您想要的通知,就不会太早。但是该代码还有其他问题。

添加观察者,触发通知,然后删除观察者没有任何意义。您不妨直接调用该handleSaveNotification方法,而不是打扰通知。它会以更少的工作产生相同的效果。

这样做的原因是通知在发布它们的线程上同步传递。所以如果someBackgroundTask实际运行在后台线程或队列上,handleSaveNotification也会在后台运行。使用这样的通知不会让你跨线程。要在主线程上进行合并,您有几个选项,包括:

  • 使用 注册通知addObserverForName:object:queue:usingBlock:。使用该方法,您可以告诉通知中心使用哪个队列。确保保存对该方法返回的对象的引用——稍后您将需要它来删除观察者。
  • 直接调用 merge 方法,但在该方法中使用dispatch_asyncorperformSelectorOnMainThread:withObject:waitUntilDone:将合并移动到主线程。
于 2013-08-28T23:40:35.123 回答