【问题标题】:CoreData Save Permanently?CoreData 永久保存?
【发布时间】:2011-05-18 04:10:38
【问题描述】:

我一直在 iPad 应用程序中使用 Core Data,我可以成功地在应用程序内保存和获取数据。但是,当完全关闭应用程序时,完全退出,将其从多任务处理中取出,然后该数据就消失了。

那么当应用程序关闭时,Core Data 是否会在任何地方保留这些数据?还是我需要去其他地方看看?

编辑:这是在应用程序委托didFinishLaunchingWithOptions[[[UIApplication sharedApplication] delegate] managedObjectContext];,然后我在 UIView 子类中有:context_ = [(prototypeAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

这是在应用委托中预制的 NSPersistentStoreCoordinator 代码:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (persistentStoreCoordinator_ != nil) {
        return persistentStoreCoordinator_;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"prototype.sqlite"];

    NSError *error = nil;
    persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.

         Typical reasons for an error here include:
         * The persistent store is not accessible;
         * The schema for the persistent store is incompatible with current managed object model.
         Check the error message to determine what the actual problem was.


         If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.

         If you encounter schema incompatibility errors during development, you can reduce their frequency by:
         * Simply deleting the existing store:
         [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]

         * Performing automatic lightweight migration by passing the following dictionary as the options parameter: 
         [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

         Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.

         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return persistentStoreCoordinator_;
}

到目前为止,我正在使用它来获取数据:

    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
    NSEntityDescription *testEntity = [NSEntityDescription entityForName:@"DatedText" inManagedObjectContext:context_];
    [fetch setEntity:testEntity];
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"dateSaved == %@", datePicker.date];
    [fetch setPredicate:pred];

    NSError *fetchError = nil;
    NSArray *fetchedObjs = [context_ executeFetchRequest:fetch error:&fetchError];
    if (fetchError != nil) {
        NSLog(@"fetchError = %@, details = %@",fetchError,fetchError.userInfo);
    }
    noteTextView.text = [[fetchedObjs objectAtIndex:0] valueForKey:@"savedText"];

这是为了保存数据:

NSManagedObject *newDatedText;
    newDatedText = [NSEntityDescription insertNewObjectForEntityForName:@"DatedText" inManagedObjectContext:context_];
    [newDatedText setValue:noteTextView.text forKey:@"savedText"];
    [newDatedText setValue:datePicker.date forKey:@"dateSaved"];

    NSError *saveError = nil;
    [context_ save:&saveError];
    if (saveError != nil) {
        NSLog(@"[%@ saveContext] Error saving context: Error = %@, details = %@",[self class], saveError,saveError.userInfo);
    }

【问题讨论】:

  • 你是如何设置你的 managedObjectContext 的?为了在退出后保存数据,您需要设置 NSPersistentStoreCoordinator。
  • 更新了更多细节的问题。
  • 您的保存代码肯定是错误的。您绝对不得查看saveError 的值,除非对-save: 的调用返回NO。这样做是一个编程错误,并且可能使您的应用程序崩溃。 -save: 不保证会保留该变量的有效值,除非它返回 NO。所以你应该使用if (![context_ save:&saveError]) { /* read saveError */ }

标签: iphone objective-c core-data load save


【解决方案1】:

您应该发布设置 NSPersistentStoreCoordinator 并添加 NSPersistentStore 的代码。您是否有任何机会使用NSInMemoryStoreType 作为您的商店类型?因为这会导致你看到的行为。或者,您可以每次使用不同的路径到商店,这样每次都会为您提供新的商店。通常,您的商店应该在您的 Documents 文件夹中,并且在每次启动时都应该使用相同的名称。它还应该使用NSSQLiteStoreType

【讨论】:

  • 更新了更多细节的问题。
【解决方案2】:

您是否将上下文保存在正确的位置?只在 willTerminate 中进入后台应用程序状态时不保存上下文是一个常见的错误。

将上下文保存在以下 appdelegate 方法中:

-(void)applicationDidEnterBackground:(UIApplication *)application

您在插入对象后直接保存上下文,这应该足够了。保存后检查模拟器中的sqlite文件是否包含数据。

如果

noteTextView.text = [[fetchedObjs objectAtIndex:0] valueForKey:@"savedText"];

不抛出异常,在上下文中找到了一个对象。也许它不包含预期值? 将 fetchrequest 中返回的对象记录到控制台,看看是否是这种情况

【讨论】:

  • 我不明白。这里是在应用程序进入后台时加载笔记?
  • 我认为我的回答不清楚。 1.在applicationDidEnterBackground中添加保存代码。 2. 将 Logging 添加到我在回复中提到的代码行中。
【解决方案3】:

我发现了问题。事实证明,由于它使用了 UIDatePicker,在程序开始时它将日期选择器设置为今天使用:

NSDate *now = [[NSDate alloc] init];
[datePicker setDate:now];

因此,如果不使用它,它就可以完美地工作。所以目前我正在寻找这个问题的解决方案,因为这条线似乎导致了这个问题。

UIDatePicker Interfering with CoreData

【讨论】:

    【解决方案4】:

    如果您在创建项目后添加 CoreData。在lazy_init 您的 NSManagedObject 中存在出错的风险。

    -(NSManagedObjectContext*) managedObjectContext{
    if (!_managedObjectContext) {
        _managedObjectContext =[self createManageObjectContextWithName:@"name.sqlite"];
    }
    return _managedObjectContext;}
    

    这是正确的方法:

    - (NSManagedObjectContext *)managedObjectContext {
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-01
      • 1970-01-01
      • 2017-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多