0

在一个玩具 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.");
    }
  });
}

当我尝试使用此方法保存此类的子类时,我没有收到任何错误,并且保存表面上是成功的。但是,在应用程序的下一次运行中,前一次运行中存在的任何数据都不存在。如果 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.");
    }
  });
}

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

4

2 回答 2

1

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

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

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

基本上,如果它是相同的上下文,你应该可以,但如果它不是相同的,你将不得不与其他人协调更改。另外,请注意,如果您将其创建为子级,则子级上下文的保存只会将更改推送到父级,而不会保存它们。

另外,请确保您的 MOC 不是 nil ... nil MOC 将什么也不做,发送 save: 消息(或任何与此相关的消息)。

于 2012-05-24T22:01:33.430 回答
1

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

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

  1. 调用 MR_save 让 MagicalRecord 处理;IE:

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

    [[NSManagedObjectContext MR_defaultContext] save];
    [[NSManagedObjectContext MR_rootSavingContext] save];
    
于 2012-08-17T19:34:57.040 回答