【问题标题】:Why is Core Data not persisting these changes to disk?为什么 Core Data 不将这些更改持久化到磁盘?
【发布时间】:2011-02-14 22:49:42
【问题描述】:

我在模型中添加了一个新实体,它可以正常加载,但内存中的任何更改都不会保存到磁盘。我在汽车对象上设置的值在内存中工作正常,但在点击主页按钮(在模拟器中)时不会持久保存到磁盘。我在我的应用程序中的另一个实体上使用几乎完全相同的代码,并且它的值可以很好地保存到磁盘(核心数据-> sqlite3);有人知道我在这里俯瞰什么吗? Car 是托管对象,汽车对象的 NSMutableArray 中的汽车,Car 是实体,Visible 是我要设置的实体的属性。 谢谢你的帮助。 斯科特

- (void)viewDidLoad {
   myAppDelegate* appDelegate = (myAppDelegate*)[[UIApplication sharedApplication] delegate];
    NSManagedObjectContext* managedObjectContex = appDelegate.managedObjectContext;
    NSFetchRequest* request = [[NSFetchRequest alloc] init];
    NSEntityDescription* entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:managedObjectContex];
    [request setEntity:entity];

    NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Name" ascending:YES];
    NSArray* sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [request setSortDescriptors:sortDescriptors];

    [sortDescriptors release];
    [sortDescriptor release];

    NSError* error = nil;
    cars = [[managedObjectContex executeFetchRequest:request error:&error] mutableCopy];

    if (cars == nil) {
        NSLog(@"Can't load the Cars data! Error: %@, %@", error, [error userInfo]);
    }


    [request release];

}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
    Car* car = [cars objectAtIndex:indexPath.row];

    if (car.Visible == [NSNumber numberWithBool:YES]) {
        car.Visible = [NSNumber numberWithBool:NO];
        [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
    }
    else {
        car.Visible = [NSNumber numberWithBool:YES];
        [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;

    }

    }

这是我的持久存储协调器选项:

persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSDictionary* options =  [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES],
                    NSMigratePersistentStoresAutomaticallyOption, 
                         [NSNumber numberWithBool:YES], 
                         NSInferMappingModelAutomaticallyOption, nil];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {

}    

【问题讨论】:

    标签: iphone core-data


    【解决方案1】:

    当您将新实体添加到应用程序的托管对象上下文时,您必须随后使用托管对象上下文的 -save: 方法来保存这些更改。

    我强烈建议阅读 Apple 的 Core Data Programming Guide 以了解 Core Data 对象和方法,以及如何创建、保存、删除和修改实体。

    【讨论】:

    • 我尝试在修改现有托管对象后按照您的建议保存上下文,但仍然得到相同的结果。 “添加新实体”是指将新的 nsmanagedobject 添加到上下文中吗?我只使用与 FetchRequest 返回的预先存在的实例并尝试修改该实例。我关于实体的声明是指将实体添加到我的模型中,并且该实体的实例可以读取但不能写入,即使我的模型中的其他实体没有这个问题。这是有道理的还是我误解了你的建议?
    • 我误解了你的问题。尽管如此,每当您对实体进行更改时,如果您希望这些更改保持不变,则必须保存托管对象上下文。
    • 我还有一些信息;我肯定在进行保存,这是 applicationWillTerminate 中的代码: if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {} 并且此代码肯定会在退出时被调用。当我打开核心数据跟踪时,我只在保存时得到这个 sql: UPDATE ZCAR SET Z_OPT = ?在哪里 Z_PK = ?和 Z_OPT = ? CoreData: details: SQLite bind[0] = (int64)14 CoreData: details: SQLite bind[1] = (int64)1 oreData: details: SQLite bind[2] = (int64)13 什么时候也应该写一个值对于 Z_VISIBLE 但不是。
    • 感谢您的帮助。绝对让我更了解正在发生的事情,并帮助我找到问题的根源。
    【解决方案2】:

    我在这棵树上完全找错了树。

    帮助我找到问题的是使用以下执行参数打开核心数据跟踪:-com.apple.CoreData.SQLDebug 1

    原来我在选择如何显示可见值时遇到了一个逻辑问题(我没有发布相应的代码),这导致了这个错误。核心数据在做正确的事情,只有在值不同时才写入更改,但我无法判断,因为我显示的值不正确。

    【讨论】:

    • 您应该将此标记为答案,然后关闭此问题。
    【解决方案3】:

    我怀疑 Alex 的答案是正确的,但您能否发布代码以显示您创建 NSManagedObject?

    更新

    那么 Alex 是对的,你没有保存数据。既然您说您添加了一个保存例程,请分享该代码。

    【讨论】:

    • 根据我对 Alex 的评论,我并没有创建新的 NSManagedObjects,只是试图修改上面 fetch 中返回的那些。修改在内存中起作用,但不会持续存在。
    • 为了更清楚,我正在使用指向预填充数据库的代码将 storeUrl 参数填充到我的持久存储协调器实例化中。 [自我创建EditableCopyOfDatabaseIfNeeded]; NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] ​​stringByAppendingPathComponent: @"Cars.sqlite"]];
    • 我将保存代码放在新的评论中给 alex。我相信它是另一回事,因为肯定会调用 save 并且肯定会在该代码中检测到更改。它只是没有将完整的值集写入数据库。
    • 感谢您的帮助!在下面发布了答案,但根据我提供的信息,此处不会检测到错误。
    猜你喜欢
    • 1970-01-01
    • 2017-11-02
    • 2022-01-19
    • 2020-10-08
    • 2016-10-31
    • 2011-04-02
    • 2015-02-21
    • 1970-01-01
    • 2018-01-21
    相关资源
    最近更新 更多