Базовые данные экономят только около 50% времени - PullRequest
2 голосов
/ 11 декабря 2011

Я только начал использовать Core Data с sql-lite, поэтому я немного новичок.Я основал свой код на различных онлайн-уроках и создал для справки приложение с основными данными xcode.Что бы это ни стоило, я интегрирую это в существующее приложение cocos2d.

Все шло хорошо, пока я не заметил, что сохранение не всегда работает.Сохранение контекста всегда возвращает true, но иногда я получаю старые данные, когда получаю их.Ошибки не генерируются.Я отладил, чтобы убедиться, что передаю правильные данные для сохранения, но я не вижу, что я делаю неправильно.

Вот часть моего "SaveDataManager", который обрабатывает сохранение и получение данных.Это объект экземпляра моего делегата приложения.

Функция Save.

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

Я не уверен, достаточно ли это информации, но я был бы очень признателен, если бы кто-то мог направить меня вправильное направление, почему это может происходить.

Ответы [ 2 ]

0 голосов
/ 13 декабря 2011

Решил это. Простая ошибка на самом деле. Я на самом деле удивлен, что это работает вообще. Если вы заметили в коде, который я разместил, я использовал переменные "_". Это было потому, что я синтезировал переменные, то есть "managedObjectContext = _managedObjectContext" Это переписало мои пользовательские методы получения. Не уверен, поможет ли это кому-то, но просто внимательно прочитайте о синтезировании, поскольку я долгое время избегал этого: P

0 голосов
/ 12 декабря 2011

Вам необходимо сохранить контекст в 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...