Проблема сброса / обновления NSManagedObjectContext и NSArrayController - PullRequest
4 голосов
/ 13 января 2010

У меня проблемы с отображением в пользовательском интерфейсе внешних изменений (выполненных другим процессом) хранилища данных sqlite.

У меня достаточно стандартное базовое представление данных на основе NSArrayController / table. Мое приложение получает уведомление о внесении внешних изменений в данные, после чего я делаю

[managedObjectContext reset]; // brute force, but data set is small

Проблема в том, что это удаляет все данные из таблицы. Упорядоченные объекты контроллера массива также пустые. Я думал, что последующее

* +1007 *

может помочь, но это не так. Выполнение запроса на выборку управляемогоObjectContext показывает, что данные присутствуют и обновляются, так что managedObjectContext знает об изменениях.

Любые подсказки относительно того, как "восстановить" после сброса? Или, возможно, подход сброса вообще неверен, и в этом случае есть лучший способ загрузить внешние изменения?

Ответы [ 2 ]

1 голос
/ 22 января 2010

Я не думаю, что два процесса должны работать в одной базе данных Core Data. Вероятно, лучше позволить одному процессу действовать как сервер, который владеет (и открывает) базу данных, а другой отправляет ей команды для внесения изменений. Я не думаю, что Core Data когда-либо предназначалась для поддержки нескольких процессов, говорящих с одним и тем же БД.

0 голосов
/ 03 апреля 2014

Так что я играл с этой точной ситуацией, и я не буду противоречить первому ответу - вы, вероятно, не должны этого делать, и если вам нужно, возможно, iCloud работает. Не используйте этот код. Я предоставляю его, чтобы помочь другим добраться до точки, где они могут обнаружить все проблемы, которые я не исправил, и двигаться дальше.

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

// Tear down bindings and context, create new context & rebind
[self.watcherAC unbind:@"managedObjectContext"];
[self saveAction:self]; // Optional, dependent on NSMergePolicy, etc
self.managedObjectContext = [[NSManagedObjectContext alloc] init];
self.managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
[self.managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
[self.watcherAC bind:@"managedObjectContext" toObject:self withKeyPath:@"managedObjectContext" options:nil];

// Force controller to refetch and rearrange
NSError* error;
[self.watcherAC fetchWithRequest:nil merge:NO error:&error];  // Immediate fetch
[self.watcherAC prepareContent];
[self.watcherAC rearrangeObjects];

Это обновляет содержимое tableView из хранилища на диске. (TableView привязан к контроллеру массива watcherAC)

Я обнаружил, что fetch: не сразу - это будет сделано в следующий раз через цикл выполнения для приложения. Таким образом, чтобы получить / переставить в правильном порядке, вам нужно использовать fetchWithRequest:

Я не уверен, что prepareContent: необходим, хотя, возможно, он помог устранить ошибки в контенте контроллера.

Я не смог заставить его восстановить выбор tableView, хотя это может быть связано с тем, что я делаю это в вызове делегата tableview, поэтому выбор представления не синхронизируется с выбором контроллера, независимо от того, какие хаки я пробую. Может быть, это может сработать для кого-то, но я предлагаю попытаться выяснить, как не выделять новый MOC, если у вашего представления есть привязки к нему.

...