Доступ к свойствам объектов базовых данных через привязки из объектов неосновных данных - PullRequest
0 голосов
/ 27 августа 2010

У меня есть набор данных, созданный другим приложением и сохраненный в формате XML на диске. Поскольку эти данные управляются этим другим приложением, я не хочу загружать эти данные в хранилище базовых данных по двум причинам: 1) это будет избыточное хранилище тех же данных, и 2) мне придется постоянно обновить свое собственное хранилище базовых данных, чтобы оно соответствовало обновлениям в файле XML, созданном другим приложением.

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

Для этого данные XML из другого приложения имеют постоянные уникальные идентификаторы, связанные с каждым объектом, хранящимся в файле XML. Я храню эти уникальные идентификаторы в своем собственном хранилище Core Data. При каждом запуске моего приложения я загружаю данные XML, созданные другим приложением, и затем могу получить доступ к соответствующим данным в своем собственном приложении через Core Data, выполнив запрос на выборку для управляемых объектов, соответствующих уникальному идентификатору.

OtherAppObjects представляет элементы, загруженные из данных XML. У них есть свои уникальные свойства в дополнение к uniqueID. Эти OtherAppObjects управляются NSArrayController. Затем у меня есть MyManagedObjects, которые загружаются из основного хранилища данных и имеют уникальные уникальные свойства в дополнение к уникальному ID.

У меня есть табличное представление, которое должно отображать свойства как из OtherAppObjects, так и из MyManagedObjects, поэтому я хочу иметь возможность получать доступ и устанавливать свойства MyManagedObjects через привязки из OtherAppObjects. Таким образом, я решил, что мог бы создать соответствующее свойство MyManagedObject для OtherAppObjects, и тогда я смог бы получить доступ к свойствам Core Data объекта MyManagedObject через привязки.

Например, если бы я хотел отобразить свойство "foo" OtherAppObjects и "бар" MyManagedObjects в табличном представлении, я мог бы просто привязать один столбец таблицы к NSArrayController с путем к ключу модели "foo" и привяжите второй столбец таблицы к ключевому пути модели "Соответствующий MyManagedObject.bar".

Это работает, когда не имеет дело с несколькими потоками или когда передается один контекст управляемого объекта. Но так как это «категорически не рекомендуется», я хотел попытаться сделать это правильно, обойдя один постоянный координатор хранилища, но создав отдельный контекст контекстов управляемого объекта.

Однако это ломается. Проблема заключается в том, что когда табличное представление пытается получить доступ к свойству панели, ему сначала необходимо получить доступ к соответствующему свойству MyManagedObject. Таким образом, OtherAppObject покорно создает новый контекст управляемого объекта и соответствующий запрос выборки с соответствующим uniqueID и возвращает управляемый объект. Но при этом он освобождает контекст управляемого объекта, и теперь управляемый объект больше не является допустимым, поэтому табличное представление не может получить доступ к свойству bar!

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

  1. Загрузить объекты из данных XML в мое собственное хранилище Core Data. По сути, создайте ManagedOtherAppObjects из OtherAppObjects со связью с MyManagedObjects, а затем доступ через привязки будет перетекать. Однако это означает, что на диске имеется избыточное хранилище тех же данных, и . Мне придется пересоздавать объекты ManagedOtherAppObject каждый раз, когда я запускаю приложение (поскольку файл XML обновляется довольно часто).

  2. Создание пользовательских методов установки / получения в классе OtherAppObject. Так, например, я бы создал -(NSValue *)bar и -(void)setBar:(NSValue *)newValue методы в OtherAppObject. Затем вместо привязки столбца табличного представления к пути значения ключа «СоответствующийMyManagedObject.bar» OtherAppObjects, я бы просто привязал его к «ключу» пути к ключу OtherAppObjects. Эти методы смогут извлечь соответствующий MyManagedObject и получить или установить значение в пределах контекста управляемого объекта, а затем вернуть правильное значение.

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

Полагаю, я мог бы создать обобщенные методы -(NSValue *)retrieveCoreDataPropertyUsingKeyPath:(NSString *)keyPath и -(void)setCoreDataProperty:(NSValue *)newValue usingKeyPath:(NSString *)keyPath, но мне все равно пришлось бы создавать установщики / получатели оболочки для каждого отдельного свойства.

[ОБНОВЛЕНИЕ: Хм, может быть, я мог бы просто переопределить valueForKeyPath: и setValue:forKeyPath:, и тогда все будет работать нормально?]

Это правильно, или я что-то упустил?

1 Ответ

0 голосов
/ 27 августа 2010

Один вариант варианта № 1, который стоит попробовать, - это настроить все так, чтобы у вас был один координатор постоянного хранилища, который разделяет объекты между двумя отдельными постоянными хранилищами. Вы бы сохранили MyManagedObjects (MMO) прежним, сохраняя его отдельно на диске, но тогда другиеAppObjects (OAO) могли бы быть сохранены каким-либо временным хранилищем на диске (например, в ~ / Library / Caches или чем-то еще) или просто хранилище памяти.

После запуска вы должны создать свой PSC и добавить магазин, содержащий ММО. Затем вы добавите второе хранилище в PSC (используя -[NSPersistentStoreCoordinator addPersistentStoreWithType:configuration:URL:options:error:]), прочитаете файл XML и создадите все ОАО, а затем свяжете эти объекты с этим хранилищем, используя -[NSManagedObjectContext assignObject:toPersistentStore:].

Базовые данные не позволяют напрямую моделировать отношения между объектами в разных хранилищах, но вы все равно можете выполнять поиск по уникальному идентификатору, как вы сейчас делаете, чтобы связать ММО с ОАО. Разница будет заключаться в том, что ОАО может просто использовать собственный контекст управляемого объекта для извлечения ММО, поэтому вы будете уверены, что ММО останется вокруг, по крайней мере, до тех пор, пока ОАО.

Затем, когда вы выходите из приложения, вы либо удаляете временное хранилище в ~ / Library / Caches, либо, если используете хранилище в памяти, просто позволяете ему исчезнуть в эфир, оставив другое хранилище с ММО. неповрежденный.

...