0

最近我开始了一个只需要一个商店的新应用程序(没有基于文档的应用程序)。有一段时间我很高兴我终于可以摆脱 NSManagedObjectContext 的困扰......直到我想在后台保存:-(

现在我对自己的代码感到困惑。例如:

- (void)awakeFromInsert
{
    [super awakeFromInsert];
    [self resetCard];
    self.creationDate = TODAY;
    self.dictionary = [Dictionary activeDictionary];
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center postNotificationName:NOTE_NEWCARD object:self];    
}

[Dictionary activeDictionary] 是一个 NSManagedObject 静态函数,返回指向在主线程中创建的 NSManagedObject 的指针。这将在后台保存期间导致交叉/上下文错误。因为我的程序总是从同一个存储读取,我想我可以避免这样写:

[Dictionary activeDictionaryWithContext:...]

我想使用 MagicalRecord,只要我始终使用相同的后端工作,就可以避免传递上下文指针。我应该使用哪个函数来获取该上下文?

[NSManagedObjectContext MR_defaultContext]
[NSManagedObjectContext MR_context]
[NSManagedObjectContext MR_contextForCurrentThread]

在示例中,对象在通知中发送自己,这几乎是为了引起更多冲突。

  • 在通知的情况下,我是否应该始终只发送 objectID?

在我看来,我的对象只有在主上下文中运行时才应该发出副作用操作/通知。但是,其中一些辅助操作会更改我的对象图,从而创建其他实体的新实例。

  • 如果我使用 [MagicalRecord MR_saveAll] 保存,我可以安全地省略我提到的两个有问题的函数调用吗?

  • 我是否应该假设新的后台保存上下文的对象将是我的主线程中的对象的精确副本,而不调用那些额外的函数?

现在我遇到了问题,因为我从没想过 awakeFromInsert 会为同一个商店的同一个对象运行多次。我在想这样的事情:

- (void)awakeFromInsert
{
    [super awakeFromInsert];
    if ([self managedObjectContext] == [NSManagedObjectContext MR_defaultContext]) {
        [self resetCard];
        self.creationDate = TODAY;
        self.dictionary = [Dictionary activeDictionary];
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        [center postNotificationName:NOTE_NEWCARD object:self];    
    }
}

这应该使我的 awakeFromInsert 代码只运行一次,而不是在后台保存上下文中。我担心这样做会丢失信息

4

1 回答 1

1

虽然您当然可以通过这种方式发送您的对象,但我建议您要这样做。请记住,即使在 CoreData 中使用新的父子上下文,NSManagedObjects 也不是线程安全的。如果您创建或导入对象,则需要先保存它们,然后才能在另一个上下文中使用它们。

MagicalRecord 提供了一个相对简单的后台保存 API:

[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext){
    MyEntity *newEntity = [MyEntity MR_createInContext:localContext];

    //perform other entity operations here
}];

此块为您完成所有工作,而无需担心正确设置 NSManagedObjectContext。

您不应该通过通知传递 NSManagedObjects 的另一个原因是您不知道将在哪个线程上接收通知。这可能会导致崩溃,因为同样,NSManagedObjects不是线程安全的。

您提供的通知方法的另一种替代方法是将观察者添加到NSManagedObjectContextDidSaveNotification,并合并您对该通知的更改。这只会在您的对象被保存后触发,并且通过父子关系或持久存储(旧方式)跨上下文是安全的。

于 2012-11-03T17:57:17.850 回答