【问题标题】:CoreData gets emptied after adding data into itCoreData 在添加数据后被清空
【发布时间】:2013-08-08 11:35:14
【问题描述】:

我有一个存储日期的 CoreData 实体 Tracker。 应用收到通知,CheckListViewController 在 CoreData 中输入数据长达 13 天,因此当 CheckListViewController 被关闭时,CoreData 实体 Tracker 将填充 13 行。

MainViewController(取消CheckListViewController)中,我有以下代码:

    - (void)dataSaved {
        self.checkListVC dismissViewControllerAnimated:YES completion:^{
              // fetching all the data from 'Tracker' entity and doing NSLog on it
              // all data gets logged in console without any issues
        }];
    }

现在,在我的代码中某处之后,我从实体 Tracker 获取所有数据,但返回数据为空。 CoreData 没有显示任何错误,它只是返回和空数组。

编辑: 从 CoreData 获取结果的代码

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
[request setSortDescriptors:@[sortDescriptor]];
request.predicate = (fromDate && toDate) ? [NSPredicate predicateWithFormat:@"date >= %@ AND date <= %@", fromDate, toDate] : nil;

__block NSArray* fetchedHabits;
[managedObjectContext performBlockAndWait:^{
    NSError *error = nil;
    fetchedHabits = [managedObjectContext executeFetchRequest:request error:&error];

    if (error) NSLog(@"Unknown error occurred while fetching results from CoreData, %@ : %@", error, [error userInfo]);
}];

CoreData 模型:

更新 1: 如您所见,有两个实体,即HabitTracker。当我从Habit 获取结果时,一切正常,但是当我尝试从Tracker 获取结果时,它给了我一个空数组。我有一个常见的NSManagedObjectContext 实例,因为您可以使用单个managedObjectContext 管理多个CoreData 实体。 我检查了managedObjectContext.persistentStoreCoordinator.managedObjectModel.entitiesByName,它还列出了这两个实体。

更新 2: 我将数据添加到Tracker的代码

TrackerCoreData *tracker = [NSEntityDescription insertNewObjectForEntityForName:ENTITY
                                                                     inManagedObjectContext:managedObjectContext];
tracker.date = date;
tracker.habits = habits;

// saving CoreData explicitly
NSError *error = nil;
[managedObjectContext save:&error];

【问题讨论】:

  • 你能用代码展示你如何在 coredata 中保存对象吗?
  • 很高兴看到您用来保存对象的代码。
  • @Firo:更新了我的问题。
  • 尝试删除你的performBlockAndWait,然后在主线程上执行它。还有为什么你的save 不工作?你有例外吗?
  • @Firo..with/without performBlockAndWait,不工作。当我说save 不起作用时,我的意思是即使在那之后它也不起作用。 save 不会产生任何错误。

标签: ios objective-c core-data nsmanagedobjectcontext


【解决方案1】:

您无法显示记录的原因可能有很多:

  • 数据未保存
  • 数据未正确检索
  • 数据显示不正确

所有这些都可能是复杂的场景,但您应该按此顺序检查它们。

更好的方法:将NSFetchedResultsController 用于您的主视图控制器,并让委托方法负责更新您的表视图。无需获取,无需在任何完成方法中完成任何工作 - 只需保存数据,FRC 就会更新您的表。

编辑:如何检查物理数据库
您的数据可能只存在于内存中,但实际上并未保存到数据库中。找到实际的数据库文件(在模拟器应用程序的文档文件夹中)并使用sqlite3 命令行实用程序或 Firefox 插件“SQLite Manager”检查它。

Edit2:更具体的建议
你应该确保你打电话:

[managedObjectContext save:&error]; 

还要仔细检查您的 ENTITY 宏代表什么(不是一个非常聪明的名称)。

在我看来,您在没有明显目的的情况下过度使用块方法。首先尝试使一切都在主线程上工作(一个上下文!)。仅当您遇到性能问题时,才考虑后台线程和上下文以及对 performBlock 等的调用。

【讨论】:

  • 1.数据已保存,因为我已经告诉过我正在获取 dissmissViewControllerAnimated 中的数据并且它正在显示。但后来当我获取数据时,它返回空数据。 2.当我检索数据时,我将谓词设置为nil,以便可以获取所有数据。但那是空的。 3. 没有“不正确显示”的意义,因为我是通过NSLog 检查数据,而不是通过任何 tableView 另外,我需要数据来绘制图表,这就是我不能使用 NSFetchResultsController 的原因。
  • 检查您的数据是否真的存在于 coredata 中的最佳方法是检查数据库本身。可能您拥有的数据只是“TempData”
  • 如何检查数据库本身?
  • 您能否检查一下您是否使用相同的NSManagedObjectContext 实例进行保存和获取。有时会发生不同的NSManagedObjectContexts 用于不同的操作。仅供参考:NSManagedObjectContext 不会立即保存到 DB/NSManagedDocument,它会将数据保存在内存中并在几秒钟后保存。因此,如果不同的context 用于获取其他context 保存的数据,那么它可能会显示为空白。
  • 有一个单例类管理NSManagedObjectContext。它检查context 是否不存在,然后只创建它。我已经用 CoreData 模型更新了我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-04
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
相关资源
最近更新 更多