2011-12-11 36 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