我刚开始使用带有sql-lite的Core Data,所以我有点新鲜。我基于各种教程在线创建代码,并创建了一个xcode核心数据应用程序供参考。为了它的价值,我将它集成到现有的cocos2d应用程序中。
一切都顺利,直到我注意到保存并不总是有效。虽然上下文保存总是返回true,但有时我在检索它时会返回旧数据。不会产生任何错误。我已经调试过以确保我传递了正确的数据以保存,但我无法看到“我做错了什么。”
这是我的“SaveDataManager”的一部分,它处理保存和检索数据。它是我的app delegate的实例对象。
保存功能。
- (bool) saveSongOptionData
{
NSManagedObjectContext *context = ((AppDelegate*)[[UIApplication sharedApplication] delegate]).managedObjectContext;
NSManagedObject *newData = [NSEntityDescription insertNewObjectForEntityForName:@"SongOptions" inManagedObjectContext:context];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"SongOptions" inManagedObjectContext:context];
//First check if row exists, if not create it. If so, update that row with our new high score information.
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
//Only should be 1 record, grab it
[request setFetchLimit:1];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if ([objects count] == 0) //None!! Lets create one
{
[newData setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].background] forKey:@"background"];
[newData setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].random] forKey:@"random"];
[newData setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].vibrate] forKey:@"vibrate"];
}
else
{
matches = [objects objectAtIndex:0];
[matches setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].background] forKey:@"background"];
[matches setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].random] forKey:@"random"];
[matches setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].vibrate] forKey:@"vibrate"];
}
[request release];
bool success = [context save:&error];
if (!success)
NSLog(@"%@", error.localizedDescription);
return success;
}
在我的AppDelegate中,我创建了我的“SaveDataManager”实例,并在applicationDidFinishLaunching方法中传递了类似的上下文:
self.dataManager = [[SavedDataManager alloc] init];
self.dataManager.managedObjectContext = self.managedObjectContext;
用于检索上下文等。
#pragma mark - Core Data stack
- (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;
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"TestGame" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil)
return _persistentStoreCoordinator;
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"TestGame.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
我不确定这是否是足够的信息,但如果有人可以指导我为什么会发生这种情况,我会非常感激。
答案 0 :(得分:0)
您需要在applicationWillTerminate:
中保存上下文,也可能在applicationDidEnterBackground:
中保存。我使用这段代码来保存这两种方法:
NSError *error;
if (managedObjectContext != nil)
{
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
{
// Update to handle the error appropriately.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
}
我是直接从Apple Core Data示例应用程序获得的。
答案 1 :(得分:0)
解决了它。真是一个简单的错误。我真的很惊讶它一直在工作。如果您在我发布的代码中注意到我使用的是“_”变量。这是因为我合成了变量,即“managedObjectContext = _managedObjectContext”这覆盖了我的自定义getter。不确定它是否对某人有所帮助,但只是确保阅读合成,因为我长期避免这样做:P