2015-02-20 2 views
0

Итак, проголосуйте, если вам нужно, но я готов к чему-то, потому что это делает меня сумасшедшим. У меня есть приложение core data (OS X), с паролем NSTableViews (Cell Based), подключенным через NSArrayControllers. У меня есть настройка класса Entity с некоторыми пользовательскими методами. Я могу добавлять, удалять, редактировать и делать всевозможные вещи с данными - все отлично работает.класс не является ключевым значением, совместимым с кодировкой для ключа @sum

Я решил добавить новый столбец для текущей суммы и использовать @sum, как я видел. Независимо от того, что я делаю, я все время получаю ошибку.

У меня есть сущность «Магазин» и еще одна сущность «Товар», у них есть отношение ко многим. В объекте Item у меня есть атрибут name и price.

В главном окне у меня есть два контроллера NSTableView: NSArrayController s, один для Магазина и один для предмета. Содержимое элемента NSArrayController контролируется контроллером магазина - выбранным элементом.

Я добавил новый столбец к элементу NSTableView, привязал его к контроллеру элемента и установил его путь к ключевому типу модели @ sum.price - это вызывает ошибку.

Возможно, у меня что-то не так просто, какие-то мысли о том, как это сделать правильно?

спасибо.

- [EDIT] ----

магазин NSArrayController: - Контроллер объекта - Наименование организации: Магазин

  • ManagedObjectContext
    • Обязанный Main контроллера ManagedObjectContext

Item NSArrayController:

  • объекта Контроллер

    • Наименование организации: Пункт
  • Content Set:

    • Обязанный магазин массива контроллера

    • контроллер Ключ: Выбор

    • Модель Key Path: пункт

Item NSTableView:

Первая колонка:

  • Обязанный элемент массива Contr Oller

  • контроллер Ключ: arrangedObjects

  • Модель Key Путь: имя

Вторая колонка:

  • Похоже, модель Key Path: цена

новая колонка:

  • Bound для элемента массива контроллер

  • Controller Key: arrangedObjects

  • Модель Key Путь: @ sum.price

Ошибка я получаю это: «организация, Элемент не соответствует ключевому значению для ключа «@sum»."

+0

Вы должны быть четкими и конкретными в отношении привязок. Например, «Контроллер элемента« NSArrayController »имеет привязку к содержимому, привязанную к контроллеру хранилища« NSArrayController », к ключу контроллера« выбор »,« путь к элементу ключа модели ». Связывание содержимого нового столбца связано с элементом Controller, ключ контроллера? ??, путь ключа модели '@ sum.price'." Или что на самом деле имеет место. Какие привязки объектов привязаны к чему, с помощью какого ключа контроллера и какого пути ключа ключа? Кроме того, вы оставили информацию об ошибке, например, какой класс не соответствует KVC. –

+0

@KenThomases Спасибо, см. Редактирование. – littleDrummerBoy

ответ

1

Рассмотрим первый столбец. Он связан с контроллером товара, arrangedObjects, name. Получает ли каждая ячейка массив имен? Нет, каждый получает одно имя.

Хотя эта колонка связывание иногда выражается как ключевой путь, такой как Item Controller.arrangedObjects.name, способ, которым он фактически работает, состоит в том, что столбец в целом показывает arrangedObjects, по одному элементу на строку, но name применяется к каждому элементу этого набора отдельно. Поэтому каждая ячейка имеет одно имя.

Теперь рассмотрим ваш новый столбец. Строки снова соответствуют arrangedObjects Контроллер элемента, но путь ключа модели применяется к каждому элементу индивидуально. Но путь ключа модели содержит оператор коллекции @sum, который не подходит для отдельного элемента (объект Item). Отсюда и ошибка.

Вы можете создать текстовое поле (вне таблицы), которое отображает сумму цены всех элементов выбранного хранилища. Вы привязывали бы привязку значения текстового поля к контроллеру товара, arrangedObjects, @sum.price. Текстовое поле работает иначе, чем столбец таблицы, так как у него есть одна вещь для отображения. Он действительно использует результат [ItemController valueForKeyPath:@"[email protected]"]. Оператор коллекции будет применен к коллекции.

Вы также можете связать текстовое поле Item Controller, selection, @sum.price, чтобы она выводила сумму цен пунктов выбранных в таблице элементов.

Привязки не предоставляют никакой возможности получить текущую сумму, если я понимаю, что вы подразумеваете под этим (первая строка показывает цену первого элемента, вторая строка показывает сумму цен первого и второго пунктов , и т.д.). Такая текущая сумма будет зависящей от контекста. Значение данной строки будет зависеть от значений предыдущих строк. Например, сортировка таблицы по-разному означала бы, что текущая сумма рядом с данным элементом изменится, поскольку набор элементов перед изменением. Привязки не могут этого сделать. Они не знают о позиции, указателе или братьях и сестрах.


Update:

Чтобы получить выполняющийся сумму, вам нужно не использовать привязки для столбца. Сделайте свой просмотр или оконный контроллер принятым NSTableViewDataSource, если он этого еще не сделал. Затем подключите выход dataSource к виду на столе.

В вашем классе источника данных реализуйте -tableView:objectValueForTableColumn:row:. Проверьте столбец identifier. Для любых столбцов, отличных от столбца текущей суммы, возвращайте nil, чтобы он использовал значение из привязок столбцов.

Для бегущей колонки суммы, прямолинейная, но неэффективная реализация будет что-то вроде:

NSRange range = NSMakeRange(0, rowIndex + 1); 
NSArray* rowsToSum = [self.itemController.arrangedObjects subarrayWithRange:range]; 
return [rowsToSum valueForKeyPath:@"@sum.price"]; 

Вы также должен были бы способом сообщить виду таблицы, когда ячейки в столбце Запущенных сумм должны быть перезагружается (пересчитывается). Вы должны использовать наблюдение за ключевыми значениями для наблюдения за self для изменения пути ключа @"itemController.arrangedObjects.price". Вы должны установить это в -viewDidLoad или -windowDidLoad. Не забывайте оторвать его, когда контроллер сделан.

Когда уведомление об изменении отправлено - т. Е.когда вызывается -observeValueForKeyPath:ofObject:change:context: - вы должны вызвать -reloadDataForRowIndexes:columnIndexes: в представлении таблицы, чтобы указать, что все индексы строк в столбце текущей суммы должны быть перезагружены.

Это должно работать, но оно будет ужасно неэффективным, как только вы получите значительное количество строк.

Таким образом, чтобы оптимизировать, вы должны кэшировать текущие суммы, но вам нужно быть осторожным, чтобы сделать недействительным кеш.

В основном, имеют переменную экземпляра, такую ​​как _cacheIsValid. Как и все переменные экземпляра, он будет начинать с нуля (false) по умолчанию. В поле -tableView:objectValueForTableColumn:row: вы можете проверить, действительно ли оно. Если это не так, вы должны построить его и записать, что он действителен. Затем, или если он уже был действительным, просто верните элемент для запрошенной строки.

Чтобы создать кеш, перейдите по ссылке self.itemController.arrangedObjects, вычисляя текущую сумму при прохождении и добавляя каждое значение в конец массива. Вы можете использовать массив примитивов типа C или NSMutableArrayNSNumber s, как вы предпочитаете. (Управление памяти для массивов C-стиля можно сделать проще с помощью NSMutableData для буфера.)

Вы исправите кэш в -observeValueForKeyPath:..., прежде чем говорить виду таблицы, чтобы перезагрузить бегущее столбец суммы.

Для следующего шага в эффективности вы можете перепрограммировать кэш в это время и сравнить значения с существующим кешем (если он действителен) по мере того, как вы идете. Накопите в NSMutableIndexSet индексы строк только тех строк, для которых фактически была изменена кэшированная текущая сумма, и используйте это при вызове -reloadDataForRowIndexes:columnIndexes:. Таким образом, представление таблицы только перезагружает ячейки, которые фактически изменились.

+0

Хорошо, я понимаю, что вы говорите, и я получил @sum для работы с textField - поэтому я неправильно понял, что может сделать сумма (at), облом. Да, вы правы с моим значением текущей суммы. Любые мысли о том, как это сделать? – littleDrummerBoy

+0

Я обновил свой ответ предложением о том, как реализовать столбец текущей суммы. –

+0

Я вижу, куда вы направляетесь, это работает, но ваше право, это неэффективно. Спасибо за помощь. – littleDrummerBoy

Смежные вопросы

 Смежные вопросы