Использование одного NSArrayController из нескольких XIB

У меня проблемы с отображением содержимого одного NSArrayController в двух окнах, определенных в разных XIB.

В моем главном окне (в MainMenu.xib) у меня есть NSTableView, который привязан к NSArrayController

Во втором моем XIB есть еще одно окно, содержащее NSTableView. Я создал новый NSArrayController и привязал таблицу к содержимому этого NSArrayController.

Оба NSArrayController привязаны к одному и тому же NSArray.

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

Я бы хотел использовать один и тот же экземпляр NSArrayController в обоих окнах. Таким образом, если объект добавлен в массив, оба представления будут уведомлены об изменении.

Проблема в том, что я не могу понять, как это сделать в Интерфейсном Разработчике. Я не могу привязать NSArrayController к другому NSArrayController (я получаю сообщение об ошибке времени выполнения, указывающее, что он может быть привязан только к NSArray). Подключение NSArrayController к члену NSArrayController в File's Owner тоже не поможет, так как это просто уничтожит NSArrayController, который я хочу использовать.

Думаю, я мог бы сам установить привязки в коде, но, похоже, было бы лучше использовать Interface Builder, если это возможно. Есть ли способ сделать это в Interface Builder или, может быть, лучший способ настроить все вместе?

Обновление: В ответ на ответ и комментарии Чака я попробовал следующее: -Свяжите содержимое таблицы моего NSTableView с упорядоченными объектами члена NSArrayController (если я использовал сам NSArrayController, в log: «[количество NSArrayController]: неопознанный селектор отправлен в экземпляр») -Свяжите каждый столбец в таблице с владельцем файла с помощью пути ключа модели arrayController.arrangedObjects.propertyName

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

Обычно я бы выбрал свой NSArrayController из ComboBox «Привязать к», использовал устроенные объекты в качестве ключа контроллера, а само свойство - в качестве пути ключа модели. Я не уверен, как сделать что-то подобное в этом случае - если вообще смогу.

Я сделал что-то не так в описанном выше процессе?


person Andy    schedule 17.01.2009    source источник
comment
Возможно, кто-то сможет исправить заголовок этого вопроса, я думаю, что «от» должно быть «за».   -  person Elise van Looij    schedule 08.12.2009


Ответы (4)


Лучший вариант, который мне удалось придумать, - это уведомить второго NSArrayController о том, что массив, которым он управляет, изменился, вызвав для него rearrangeObjects:. Это кажется неуклюжим, но работает.

person Andy    schedule 27.01.2009

Как насчет их настройки в качестве прокси-объектов в IB, а затем создания экземпляра фактического кода, возможно, в делегате вашего приложения?

person Ryan Townshend    schedule 27.01.2009
comment
Единственная ссылка на настраиваемые прокси-объекты, которую я смог найти, - это developer.apple.com/documentation/DeveloperTools/Conceptual/, но только для iPhone. Я что-то пропустил? - person Andy; 28.01.2009

Вы можете заставить оба NSArrayController обновляться через KVO при добавлении массива в. Хитрость в том, что вы должны наблюдать и добавлять в массив в соответствии с KVO.

Вам нужен какой-то объект, владеющий массивом, назовем его «моделью». Массив должен быть ключом к объекту, назовем этот ключ contentArray. Затем, когда вы добавляете / удаляете из, вы должны сделать это, сначала вызвав mutableArrayForKey в «модели», чтобы получить «contentArray». Тогда должно работать добавление / удаление из массива, например:

Controller1 привязан к self.model.contentArray

Controller2 привязан к self.model.contentArray

//this method is on the "model" object
-(void)addContent(id content)
{
    NSMutableArray* contentArr = [self mutableArrayForKey:@"contentArray"];
    [contentArr addObject:content]; //this will trigger KVO notifications
}

В качестве альтернативы вы можете сделать уведомления KVO вручную следующим образом:

-(void)addContent(id content)
{
    [self willChangeValueForKey:@"contentArray"];
    [m_contentArray addObject:content];
    [self didChangeValueForKey:@"contentArray"];
}
person Tom Dalling    schedule 30.06.2009

Нет причин, по которым наличие двух контроллеров массива должно приводить к тому, что одно представление не обновляется при обновлении через другое. Если этого не происходит, похоже, что ваши KVO-уведомления где-то теряются. Скорее всего, вы напрямую редактируете массив (возможно, в методе add: подкласса NSArrayController?), Не отправляя соответствующие уведомления об изменениях.

person Chuck    schedule 19.01.2009
comment
Как мне это сделать? Я не могу привязать NSArrayController во втором XIB к тому, что находится в File's Owner, поскольку NSArrayControllers может быть привязан только к NSArrays. Что я использую в качестве пути в моем NSTableView для извлечения данных из этого NSArrayController? - person Andy; 19.01.2009
comment
Это просто нормальное кодирование "ключ-значение". Допустим, владелец вашего файла хранит ссылку на контроллер как arrayController. Вы бы связали представление таблицы с владельцем файла с помощью arrayController пути ключа модели. - person Chuck; 21.01.2009
comment
Но как тогда таблица узнает, что отображать в каждом столбце? Обычно я привязываю столбец к упорядоченным объектам NSArrayController, определенным в XIB. Как мне добраться до привязанного NSArrayController для отображения правильных значений в каждом столбце? - person Andy; 22.01.2009
comment
Как я уже сказал, вы попадаете в NSArrayController с помощью File Owner.arrayController. Это то же самое, что и обычная привязка к NSArrayController, только вы получаете доступ к нему через владельца файла, а не непосредственно в вашем пере. - person Chuck; 22.01.2009
comment
Я все еще не могу заставить его работать. :( Я описал свои действия в редактировании своего вопроса - сделал ли я что-то не так, исходя из того, что вы описали выше? - person Andy; 23.01.2009
comment
Я отредактировал свой ответ, чтобы немного приблизиться к корню проблемы. Извините за предыдущий ответ, который потратил впустую. Я был в плохой погоде, и, думаю, мой мозг был немного запутан. Вы можете спокойно игнорировать то, что я сказал ранее, потому что это дополнительная работа, которая не затрагивает суть проблемы. - person Chuck; 23.01.2009
comment
Не беспокойтесь, пока вам помогли. :) Я использую метод addObject: NSArrayController (без подкласса). Есть ли что-то, что я должен делать в дополнение к этому? - person Andy; 24.01.2009