Автосохранение CoreData и не загрузка всех данных после автосохранения - PullRequest
0 голосов
/ 23 февраля 2012

У меня есть подкласс NSPersistentDocument, использующий подклассы NSManagedObject для моих данных.

Когда открывается новый документ, я выполняю некоторую инициализацию структур данных (тривиальное количество заполненных полей). Я заметил, что документ без названия автоматически сохраняется, и при повторном открытии приложения этот документ загружается. Если приложение закрывается, пользователю не (по умолчанию) не предлагается диалоговое окно сохранения. Если окно закрывается, пользователь делает.

Первый вопрос:

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

Я попытался заполнить:

- (void)applicationWillTerminate:(NSNotification *)aNotification

Чтобы активировать документ для сохранения. Вызов save: для контекста в этот момент дает ошибку. Из того, что я могу сказать, это потому, что пользователь еще не сохранил файл самостоятельно. Кроме того, вызов [self close]; или [[self windowForSheet] close]; закрывает окно без сохранения.

Как заставить диалог сохранения появиться? Как я могу удалить документ без названия?

Второй вопрос (нет, я не могу сосчитать):

Поскольку при запуске приложения может существовать или не иметься документ без названия, я пытаюсь отслеживать состояние в другой модели. Я уже обнаружил, что исходные данные (на которые я ссылался ранее) присутствуют при появлении документа без названия. Моя другая модель имеет некоторые метаданные, включая флаг / состояние успеха для заполненных данных. Как только заполненные данные все на месте и исправлены, состояние указывается как таковое. К сожалению, хотя мои заполненные данные загружаются, когда приложение запускается с уже существующим документом без названия, класс метаданных - нет.

Прошу прощения за грубость кода, на данный момент я все испортил до тех пор, пока не увижу, что он работает так, как я хочу, прежде чем отполировать его обратно:

- (bool) createGameState {
  NSEntityDescription* description = [NSEntityDescription entityForName:[GameState name] inManagedObjectContext:[self managedObjectContext]];
  NSFetchRequest* req = [[NSFetchRequest alloc] init];
  [req setEntity:description];

  NSError *error = nil;
  NSArray *array = [[self managedObjectContext] executeFetchRequest:req error:&error];
  [req release];
  req = nil;

  GameState* result = nil;
  if (array) {
    NSUInteger count = [array count];
    if (!count) {
      // Create the new GameState.
      DebugLog(@"Creating GameState");
      result = [NSEntityDescription insertNewObjectForEntityForName:[GameState name] inManagedObjectContext:[self managedObjectContext]];
      [result setIsLoaded:[NSNumber numberWithBool:NO]];
    } else {
      if (count > 1) {
        NSLog(@"WARNING: Potentially Corrupt Game State. found: %lu", count);
      }
      result = [array objectAtIndex:0];
      if ([result isLoaded]) {
        [self variantLoaded];
      } else {
        // In this case, we have an aborted set-up. Since the game isn't
        // playable, just refuse to create the GameState. This will
        // force the user to create a new game.
        return NO;
      }
    }
  } else {
    DebugLog(@"error: %@", error);
  } 

  [game setState:result];
  return result;
}

Обратите внимание, что массив всегда присутствует, а число всегда равно нулю. Нет, я нигде явно не звоню save:. Я полагаюсь на стандартное автосохранение или на пользователя, выполняющего сохранение.

EDIT:

Я установил приложение Core Data Editor. Оказывается, проблема не в сохранении данных, а в их загрузке. (Примечание: из-за другой проблемы приложение сохраняет как двоичный файл, когда ему поручено сохранить как XML, что вызывает сильные удары головой.)

Я разбил его на простейший код, который должен собирать все объекты типа GameState в массиве. Он не получает ничего, несмотря на то, что в сохраненном файле явно присутствуют объекты соответствующего типа:

  NSManagedObjectContext* moc = [self managedObjectContext];
  NSEntityDescription* entity = [NSEntityDescription entityForName:@"GameState" inManagedObjectContext:moc];

  NSFetchRequest* req = [[NSFetchRequest alloc] init];
  [req setEntity:entity];


  NSError *error = nil;
  NSArray *array = [moc executeFetchRequest:req error:&error];

Массив не равен нулю, но [array count] равен 0.

На данный момент, я думаю, это что-то простое, что я пропускаю.

Второе редактирование:

Я добавил -com.apple.CoreData.SQLDebug 5 и сохранил как SQLite. Вызов executeFetchRequest не генерирует журналы отладки. Я вижу запись INSERT INTO ZGAMESTATE в журналах. Кажется, что executeFetchRequest не передается бэкэнду.

Третий РЕДАКТИРОВАТЬ (этот горит):

Я создал новый проект xcode, используя базовые данные (как и в случае с другими). Я скопировал только одну эту функцию (заглушка там, где это необходимо) и добавил вызов к ней в windowControllerDidLoadNib. В этом новом проекте код выше работает.

1 Ответ

0 голосов
/ 09 марта 2012

Нашел проблему.

Я ошибочно загружал объекты в вызове Document - (id) init.Переместился на windowControllerDidLoadNib (что я и сделал в тестовой версии) и все заработало.

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