NSManagedObjectContext保存但不会持久

时间:2012-05-24 21:18:04

标签: ios xcode core-data nsmanagedobject nsmanagedobjectcontext

在玩具iOS项目中,我使用MagicalRecord在应用程序委托中设置CoreData堆栈。使用以下代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  [MagicalRecord setupCoreDataStackWithStoreNamed:@"ToyProject.sqlite"];
  [[NSManagedObjectContext MR_defaultContext] setUndoManager:[[NSUndoManager alloc] init]];

...
}

我有一个NSManagedObject的子类,我正在编写(NSRailsManagedObject - 我分叉NSRails并添加了CoreData支持),我给它一个saveContext方法:

- (void)saveContext {
  dispatch_async(dispatch_get_main_queue(), ^{
    @try {
        NSError *error = nil;
        if (![self.managedObjectContext save:&error]) {
          NSLog(@"Failed to save core data: %@", [error localizedDescription]);
        } else {
          NSLog(@"\"Successfully\" saved your data.");
        }
    }
    @catch (NSException *exception) {
      NSLog(@"Couldn't save your data! Try again later :(");
    }
    @finally {
      NSLog(@"Look, I don't know what else to tell you, mang.");
    }
  });
}

当我尝试使用此方法保存此类的子类时,我收到NO错误,并且表面上保存成功。但是,在下一次运行应用程序时,上一次运行中没有任何数据存在。如果saveContext方法包含以下代码,则它可以正常运行:

- (void)saveContext {
  [[NSManagedObjectContext MR_defaultContext] MR_save];
}

此外,如果我将两者混合,则保存不会保留数据。

- (void)saveContext {
  dispatch_async(dispatch_get_main_queue(), ^{
    @try {
        NSError *error = nil;
        if (![[NSManagedObjectContext MR_defaultContext] save:&error]) {
          NSLog(@"Failed to save core data: %@", [error localizedDescription]);
        } else {
          NSLog(@"\"Successfully\" saved your data.");
        }
    }
    @catch (NSException *exception) {
      NSLog(@"Couldn't save your data! Try again later :(");
    }
    @finally {
      NSLog(@"Look, I don't know what else to tell you, mang.");
    }
  });
}

我真的不知道还有什么可以尝试的。谁能指出我正确的方向?

2 个答案:

答案 0 :(得分:1)

嗯,我从未使用过MagicalRecord,但我怀疑你的问题与它有什么关系。不幸的是,您没有提供正确的信息。

具体来说,您的托管对象上下文是什么?也就是说,self.managedObjectContext返回什么,以及如何创建该上下文?

它与默认MR上下文的关系是什么?我认为MR做了一些线程特定的上下文映射,所以如果你要使用MR,你应该坚持使用MR。

基本上,如果它是相同的上下文,你应该没问题,但如果它不是同一个,你将必须与其他人协调变化。另外,请注意,如果您将其创建为子项,则子项上下文的保存仅将更改推送到父项,它不会保存它们。

另外,请确保您的MOC不是零...没有MOC将不执行任何操作发送了save:消息(或任何消息)。

答案 1 :(得分:1)

MagicalRecord创建的defaultContext嵌套在另一个(主要是私有的)上下文中,称为rootSavingContext。结果是在嵌套(子)上下文中调用Core Data的标准-save方法写入磁盘,而只是将其更改传播回父rootSavingContext。

基本上,我认为你有两个选择:

  1. 调用MR_save并让MagicalRecord处理它;即:

    [[NSManagedObjectContext MR_defaultContext] MR_save];
    
  2. 在defaultContext上调用NSManagedObjectContext保存,然后通过在父上下文中调用save来跟进它:

    [[NSManagedObjectContext MR_defaultContext] save];
    [[NSManagedObjectContext MR_rootSavingContext] save];