【发布时间】:2023-03-05 22:05:01
【问题描述】:
我已经开始在我当前的项目中集成核心数据,这是我第一次使用它。
我已经设法将新对象写入我的NSManagedObjectContext 并读出它们。我的问题是,关闭应用程序后所有对象都丢失了。这是添加新对象的函数之一:
-(void)addExpenseWithValue:(NSNumber *)value name:(NSString *)name type:(BOOL)type andDate:(NSDate *)date{
//get the right managed object context
NSManagedObjectContext *context = self.managedObjectContext;
//creat a new expense in context
NSManagedObject *newExpense = [NSEntityDescription insertNewObjectForEntityForName:@"Expense" inManagedObjectContext:context];
//Get Number representation of month and year
NSNumber *monthNumber = [self getMonthNumber:date];
NSNumber *dayNumber = [self getDayNumber:date];
//set values of the expense
[newExpense setValue:[NSDate date] forKey:@"date"];
[newExpense setValue:value forKey:@"value"];
[newExpense setValue:name forKey:@"name"];
[newExpense setValue:[NSNumber numberWithBool:type ] forKey:@"expenseType"];
[newExpense setValue:monthNumber forKey:@"month"];
[newExpense setValue:dayNumber forKey:@"day"];
[self storeData];
}
-(void)storeData{
NSError *error = nil;
[managedObjectContext save:&error];
}
这些对象实际上是存储的,之后我可以将它们读出。据我所知,这与persistentStore 和persistentStoreCoordinator 有关。我的appDelegate 实现了以下方法:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
stringByAppendingPathComponent: @"<Project Name>.sqlite"]];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
if(![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:storeUrl options:nil error:&error]) {
/*Error for store creation should be handled in here*/
}
return persistentStoreCoordinator;
}
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil] ;
return managedObjectModel;
}
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
更新:
我添加了一个小测试函数,以试验它在第一个 viewController 中被调用:
-(void)test{
NSArray* stores = [[managedObjectContext persistentStoreCoordinator]persistentStores];
if ([stores objectAtIndex:0]==nil) {
NSLog(@"no stores found");
}
else
NSLog(@"%d", [stores count]);
}
managedObjectContext 是在 appdelegate 中启动的应用程序 NSanagedObjectContext。它存在,数组被分配,但计数保持在 0。
2012-03-06 20:09:37.772 DailyBudget[1533:fb03] *** Terminating app due to uncaught
exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond
bounds for empty array'
*** First throw call stack:
(0x135f052 0x174fd0a 0x134b674 0x3c6a 0x3894 0x46cfbf 0x46d21b 0x4838b1 0x46cfbf
0x46d21b 0x46e0f1 0x3dcfec 0x3e2572 0x3dc72b 0x3cbbc2 0x3cbce2 0x3cbea8 0x3d2d9a 0x25b3
0x3a39d6 0x3a48a6 0x3b3743 0x3b41f8 0x3a7aa9 0x1f57fa9 0x13331c5 0x1298022 0x129690a
0x1295db4 0x1295ccb 0x3a42a7 0x3a5a9b 0x2488 0x23e5 0x1)
terminate called throwing an exception(gdb)
在发生错误的那一刻,我有以下对象:
我错过了什么?
【问题讨论】:
-
错误为零? [managedObjectContext save:&error] 是 TRUE 吗?
-
如果您使用
NSArrayControllers 来显示您的数据,请确保它们具有setAutomaticallyPreparesContent:YES(类似于 IB 中的“准备内容”)。 -
您能否检查持久存储创建是否正常? -[NSPersistentStoreCoordinator persistentStores] 返回什么?
-
嗨。我不使用数组来显示它。到目前为止,我只是使用了一些 NSLog 输出来查看是否有东西。在重新启动之前,我得到了我保存的所有内容,重新启动后它就消失了。今晚我将发布更多退货和代码 - 在课堂上的自动取款机上,现在还不能这样做。
-
添加了很多代码、日志和对象计数 =) 希望对您有所帮助。
标签: objective-c ios cocoa core-data persistent-storage