Совместим ли NSCollectionView с CoreData - PullRequest
1 голос
/ 19 января 2011

Обновление: этот поток определяет ошибку в NSCollectionView, когда представленные объекты представления коллекции являются NSManagedObjects.Ошибка вызывается следующим образом:

(a) Удалить объекты из NSArrayController (b) Выполнить сохранение в связанном nsmanagedobjectcontext в любое время после удаления и до того, как NSCollectionView завершит анимацию.

Эти проекты на github демонстрируют проблему.

https://github.com/artifacts/NSCollectionViewCoreDataBug https://github.com/iracooke/CoreDataCollectionViewCrashing

Исходный вопрос ниже

У меня есть настройка NSCollectionView с привязкой содержимого, привязанной к selectedObjects NSArrayControllerосновных данных объектов.В моем Представлении Элемента Коллекции (прототип для представления NSCollectionView) у меня есть несколько элементов управления, связанных с помощью представляемого объекта моего элемента коллекции с объектами базовых данных.

По большей части это работает нормально.

Я сталкиваюсь с исключением objc_exception при попытке удалить объекты из моего ArrayController.Я удаляю эти сущности, просто вызывая;

[myArrayController removeObject:managedObjectToDelete];

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

Изучение стека вызовов при возникновении исключения показывает, что сбой возникает, когда NSCollectionView получает свой метод _endOfAnimation.Это, в свою очередь, инициирует другие методы, связанные с отменой привязки (вероятно, из свойств моей сущности с элементами управления на мой взгляд).

Еще один бит информации заключается в том, что сущность, с которой я работаю, не имеет отношения к другим сущностямв моей модели.

Мне кажется, что возникает следующая проблема:

  • Когда я удаляю объекты из моего NSArrayController, они, в свою очередь, удаляются из контекста.
  • Послеудаление из контекста, объекты превращаются в ошибки
  • NSCollectionView сохранил ссылки на объекты (теперь ошибки).Он пытается очистить их в конце анимации (отмены привязки и т. Д.).
  • Когда NSCollectionView пытается очистить привязки к объекту, он заставляет данные ядра пытаться вызвать ошибку на объекте (надеюсь, я получил свою терминологию прямо здесь).Это вызывает ошибку, поскольку объект еще не был сохранен на диск.

Единственный способ предотвратить это - сохранить объекты в хранилище (сохранив их) доудаление.Это работает, но только в хакерской манере, так как мне нужно убедиться, что один раунд удаления завершен перед повторным сохранением ... и поскольку ошибка возникает во время анимации ... после некоторой задержки ... и два сохранения подрядВ результате снова возникает та же ошибка.

Означает ли это, что я не могу использовать NSArrayController с базовыми данными для заполнения NSCollectionView?Если нет, что я делаю не так?Есть ли лучший способ обойти эту проблему?

Ответы [ 2 ]

2 голосов
/ 28 июня 2011

Прямой, но скучный ответ: я могу подтвердить, что NSArrayController, поддерживаемый Базовыми данными, может заполнять NSCollectionView, с различными объектами GUI в элементе NSView коллекции, привязанными к сгенерированному «Элементу представления коллекции» и ссылающимися на различные объекты Core Data вдольдорожка.Программно удаляются (и переупорядочиваются) элементы NSArrayController. Работает (с бесплатной анимацией).

Возможно, некоторые привязки или другие зависимости внутри вашего Collection View вызывают проблему?Или проблема многопоточности с контекстом (ами) управляемого объекта?

1 голос
/ 05 августа 2011

Вы можете обойти эту проблему, добавив (назначить) свойство к вашему CollectionItem, которое указывает на соответствующий ArrayController.

Это свойство может быть установлено в - [YourNSCollectionViewSubClass newItemWithRepresentedObject:].

Затем вы можете наблюдать за расположенными объектами в каждом предмете. Когда он изменяется, и item.representedObject больше не содержится в arrangeObjects, Вы устанавливаете item.representedObject в ноль. В моем тестировании (10.6.8) это вызывает очистку привязки до того, как CoreData превратит объекты в ошибки. (Мои объекты имеют отношения, а представление элементов имеет привязки к ним).

Кстати: эта проблема не ограничивается сохранением во время анимации, Комбинации отмены / возврата / сохранения могут также вызвать это.

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

Поэтому я (неохотно) решил начать наблюдение в -newItemWithRepresentedObject: и остановите его в -dealloc элемента.

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

Вот мой код наблюдателя:

    - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if( object == self.arrayController && [keyPath isEqualToString: @"arrangedObjects"] ) {
        if( NO == [self.arrayController.arrangedObjects containsObject: self.representedObject] ) {
            self.representedObject = nil;

            for(NSView *subview in [self.view subviews]) {
                if( [subview isKindOfClass: [NSControl class]] ) {
                    [(NSControl *)subview setEnabled: NO];
                }
            }
        }
    } else {
        [super observeValueForKeyPath:keyPath ofObject: object change:change context:context];
    }
}
...