2011-12-11 69 views
2

我刚开始在sql-lite中使用核心数据,所以我有点新。我基于各种教程在线创建了一个xcode核心数据应用程序供参考。对于它的价值,我将它整合到现有的cocos2d应用程序中。核心数据只能节省大约50%的时间

一切都还好,直到我注意到储蓄并不总是工作。尽管上下文保存总是返回true,但有时我在取回旧数据时会返回该数据。不会产生错误。我已经调试过,以确保我传递了正确的数据来保存,但我不知道我做错了什么。

这是我的“SaveDataManager”的一部分,它处理保存和检索数据。它是我的应用程序委托的实例对象。

保存功能。

- (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

你是否从主线程保存? – user170317

+0

好问题,基本上我这样称呼保存功能: AppDelegate * d =(AppDelegate *)[[UIApplication sharedApplication] delegate]; [d.dataManager saveSongOptionData]; 您认为这可能是一个问题吗? – Arbel

回答

0

解决了它。真的很简单的错误。我真的很惊讶它一直在工作。如果你注意到我发布的代码中使用了“_”变量。这是因为我合成了变量,即“managedObjectContext = _managedObjectContext”这覆盖了我的自定义getters。不知道它是否会帮助某人,但只是确保阅读综合,因为我很长时间以来避免这样做:P

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示例应用程序获得此代码。

+0

试图添加这个,但仍然是相同的行为。 – Arbel

+0

您可以尝试每次保存重要信息时添加此语句。在查看代码后,您对managedObjectContext的调用看起来很奇怪,并且可能很麻烦。您应该查看Core Data如何在[Core Data Books]中实现。(http://developer.apple.com/library/ios/#samplecode/CoreDataBooks/Introduction/Intro.html#//apple_ref/doc/uid/ DTS40008405)。而且您还应该查看自定义托管对象模型。 – gurooj