Ios 核心数据仅节省约50%的时间

Ios 核心数据仅节省约50%的时间,ios,iphone,sqlite,core-data,cocos2d-iphone,Ios,Iphone,Sqlite,Core Data,Cocos2d Iphone,我刚开始使用SQLLite的核心数据,所以我有点新。我的代码基于各种在线教程,并创建了一个xcode核心数据应用程序供参考。不管它值多少钱,我将把它集成到一个现有的cocos2d应用程序中 一切都很顺利,直到我注意到储蓄并不总是有效。虽然上下文保存总是返回true,但有时在检索旧数据时会返回旧数据。不会产生任何错误。我已经进行了调试,以确保传递的数据正确无误,但我看不出我做错了什么 这里是我的SaveDataManager的一部分,它处理保存和检索数据。它是我的应用程序委托的实例对象 保存功能

我刚开始使用SQLLite的核心数据,所以我有点新。我的代码基于各种在线教程,并创建了一个xcode核心数据应用程序供参考。不管它值多少钱,我将把它集成到一个现有的cocos2d应用程序中

一切都很顺利,直到我注意到储蓄并不总是有效。虽然上下文保存总是返回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实例,并像在ApplicationIDFinishLaunching方法中那样将上下文传递给它:

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;
}

我不确定这是否是足够的信息,但如果有人能为我指明发生这种情况的正确方向,我将不胜感激

您需要将上下文保存在applicationWillTerminate:中,也可能保存在ApplicationIdentinterBackground:中。我使用这段代码在这两种方法中进行保存:

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

我直接从一个苹果核心数据示例应用程序中得到了这个

您需要将上下文保存在applicationWillTerminate:中,也可能保存在ApplicationIdentinterBackground:中。我使用这段代码在这两种方法中进行保存:

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

我直接从一个苹果核心数据示例应用程序中得到了这个

解决了它。一个简单的错误。我真的很惊讶它居然能起作用。如果您注意到我发布的代码中使用了uu变量。这是因为我已经合成了变量,即managedObjectContext=\u managedObjectContext,它重写了我的自定义getter。我不确定这是否会对某人有所帮助,但请确保仔细阅读合成方面的内容,因为我很长一段时间都没有这样做:P

解决了这个问题。一个简单的错误。我真的很惊讶它居然能起作用。如果您注意到我发布的代码中使用了uu变量。这是因为我已经合成了变量,即managedObjectContext=\u managedObjectContext,它重写了我的自定义getter。不确定它是否会对某人有所帮助,但请确保阅读有关合成的内容,因为我很长一段时间都没有这样做:P

您确实从主线程保存吗?好问题,基本上我这样调用保存函数:AppDelegate d=AppDelegate[[UIApplication sharedApplication]delegate];[d.dataManager saveSongOptionData];您认为这可能是一个问题吗?您确实从主线程保存吗?好问题,基本上我这样调用保存函数:AppDelegate d=AppDelegate[[UIApplication sharedApplication]delegate];[d.dataManager saveSongOptionData];您认为这可能是个问题吗?已尝试添加此语句,但行为仍然相同。您可以尝试在每次保存重要信息时添加此语句。在查看了代码之后,对managedObjectContext的调用似乎很奇怪,而且可能很麻烦。您应该了解核心数据是如何在中实现的。您还应该研究自定义托管对象模型。尝试添加此语句,但行为仍然相同。您可以在每次保存重要信息时尝试添加此语句。在查看了代码之后,对managedObjectContext的调用似乎很奇怪,而且可能很麻烦。您应该了解核心数据是如何在中实现的。您还应该研究定制的托管对象模型。