2011-09-06 46 views
0

我有以下问题:如何保存PersistentStore

我有一个应用程序与UITableView作为根视图。在这个tableView是不同的条目和每个条目(可以由用户创建),我也添加一个persistentstore到我的应用程序。

因此,当我从头开始应用程序(没有保存的数据等)并添加一个条目时,persistentStore也会创建,当我点击tableViewCell时,我可以将数据保存在此生成的persistentStore中。如果我正在创建一个条目并且在一次单独运行期间观看条目,这可以正常工作。

如果我关闭应用程序,然后重新启动,单击相同的条目,我收到以下错误信息:

NSFetchRequest *allUsers = [[NSFetchRequest alloc] init]; 
[allUsers setAffectedStores:[NSArray arrayWithObject:[[self.tableViewContext persistentStoreCoordinator] persistentStoreForURL:storeURL]]]; 

*终止应用程序由于未捕获的异常“NSInvalidArgumentException ',原因:'* - [NSArray initWithObjects:count:]:尝试在对象[0]处插入零对象'

所以看来我想添加一个sto这实际上是零,因为(我猜是这样)系统在这个给定的storeURL下找不到任何商店(这与我在第一次运行时创建商店的商店相同)。

所以我想persistentStore不在第二次运行中,所以它不会在创建它的第一次运行中正确保存。

那么如何将persistentStore保存到persistentStoreCoordinator之后?

更新:

我想我已经确定的主要问题。 persistentStoreCoordinator在第一次运行后已更改。那么如何在关闭应用程序之前保存所有这些内容(managedObjectContext,persistentStoreCoordinator)?

有人可以帮我吗?

更新2

这里是我创建存储:

NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentPath = [searchPaths objectAtIndex:0]; 
    NSString* storeFileName = [NSString stringWithFormat:@"%@",newItem.name]; 
    NSURL *storeURL = [NSURL fileURLWithPath:[documentPath stringByAppendingPathComponent:storeFileName]];        
    NSError* saveToStoreError; 
    if(![[self.addContext persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&saveToStoreError]){ 
    NSLog(@"Error: %@, %@", saveToStoreError, [saveToStoreError userInfo]); 
    abort(); 
    } 
    else 
    { 
     NSError *saveStoreError; 
     if(![self.addContext save:&saveStoreError]) 
     { 
      NSLog(@"Saving Data wasn't possible!"); 
     } 
    } 

更新3 所以,大量的测试后,这里是我的结果:

  • 商店的创建工作正常。我可以创建多个商店,只要我在应用程序的一次运行中,就可以访问并填充它们。

因此,重新启动我的应用程序时发生了一些变化。我认为错误必须与managedObjectContext,persistentStoreCoordinator或商店的SAVING关联。

我应该更改我的应用程序委托中用于设置managedObjectContext或persistentStoreCoordinator的任何设置吗?

谢谢!

+0

我想你已经猜到了你的问题的直接原因:没有你正在请求的持久存储URL的文件。为什么没有文件与创建持久存储的代码有关。您需要将其添加到问题中。 – morningstar

+0

我认为CREATION不是问题,因为它在第一次运行时都工作正常,所以商店必须在给定的URL下。但它似乎在第二轮运行,所以我想我没有妥善保存它。但我认为创作应该没问题。 – andi1984

+0

我想你可能会误解一些重要的核心数据应该如何使用。为表中的每个条目创建一个新的持久存储是非常罕见的。商店旨在保存整个对象图不是零碎的。 – TechZen

回答

0

这很简单。

我没有设置addPersistentStoreWithType重新启动后,我试图从这家商店获取数据的视图。

对不起,这篇文章。简单易行;-) bangingmyheadonthewall

+0

这很好!您已经记录了所有步骤,并发生在解决方案上。现在其他人将受益。协作系统非常棒。 :) –

+0

确实。我喜欢stackoverflow和所有谁是帮助我找到我或多或少严重的问题;-) – andi1984

0

看看Xcode模板中基于Window的应用程序。

这会为您创建一个完整的Core-Data堆栈 - 持久存储,持久存储协调器和受管对象上下文。

假设你的应用程序没有特别要求它,你应该只有一个持久存储。实际上,这是写入数据的文件。看看你的代码,看起来你每次保存数据时都试图创建自己的商店。

您应该从我上面建议的模板中复制核心数据堆栈方法。您无需亲自参考持久性存储或持久性存储协调器。您所需要的只是由应用程序委托创建的托管对象上下文。

+0

我已经在使用基于窗口的应用程序。但是这并不能解决问题。我认为主要问题是,persistentStore在每次重新启动后都会更改。这是通常的情况吗? – andi1984

+0

我已经更新了我的答案以解释更多。 –

0

要保存托管对象上下文,请在关闭应用程序之前添加新的永久性存储库&后使用NSManagedObjectContext的“save:”方法。然后,要检查持久性存储是否已正确添加,请使用NSPersistentStoreCoordinator“persistentStores”方法确定可用的有效存储。

+0

谢谢你。 结果如下: 在调用addPersistentStoreWithType ...之后,有2个存储区(应用程序委托的主存储区和这个新添加的一次),因此在调用此方法之前多存储一个存储区。因此,我认为这家店保存了。 但是,关闭应用程序并重新启动后,再次只有一个商店(主店)。 所以我认为它有一些事情,persistentStoreCoordinator和managedObjectContext正在改变重新启动。有没有办法将它们冻结? – andi1984

1

您说出问题的方式导致我怀疑某种混淆。

persistentStore在每次重新启动后都在更改。这是通常的情况吗?

是的! NSPersistentStore是任何其他对象的Objective-C对象。因此,它在发布时并不是一成不变的。您需要每次重新创建它。

NSPersistentStore的持久性是它指向的文件。但是每次运行应用程序时,都必须重新创建一个新的NSPersistentStore对象,可能会使其指向同一个文件(由url参数定义为initWithPersistentStoreCoordinator:configurationName:URL:options:)。

那么你如何设置你的storeURL变量?

+0

嗯,我不明白。所以我有一个我创建的NSPersistentStore,然后在同一个运行中访问这个商店,所有的作品都完美无缺。所以它可以访问这家商店。 或者你的意思是NSPersistentStoreCoordinator? 所以我创建了商店并保存了商店。所以我想我必须在重新启动后重新设置我的NSPersistentStoreCoordinator。这是你在上面谈论的同一个话题吗? 令我困惑的是,[__persistentStoreCoordinator persistentStores]在关闭应用程序之前具有更高的值,因为重新启动应用程序后。 – andi1984

0

我不知道这个问题是不是核心数据调用,如果/当他们被调用?

当你“关闭应用程序并重新开始”...应用程序终止在中间,还是它背景? IIRC会巧妙地影响你的App Delegate中调用的内容。根据WRT核心数据的排列方式,可能有些意外被称为(或错过)。

如果您追踪App Delegate中的每个单独的核心数据相关方法(或者它们可能位于的任何位置),我会感兴趣的是看看会发生什么情况,以查看是否可以更清楚地捕获它。 (如果有一个最小的测试用例发布在某处,请分享!)

+0

嗨, 我认为我应该将RESTART改为STOPP APP并重新开始。所以我在iOS模拟器上测试它,然后退出并重新启动它,然后出现这种情况。 因此,对于我(作为初学者),它似乎是这样的: 如果我创建一个新条目,我的应用程序委托的当前NSPersistentStoreCoordinator知道它,当我停止模拟器并重新启动它时,新的“storeCoordinator,它没有关于这些商店的信息。所以这就是我的感觉,那里有什么问题,但也可能是完全无稽之谈。 : -/ – andi1984