Наблюдаемый объект не зарегистрирован как наблюдатель - PullRequest
0 голосов
/ 12 апреля 2011

У меня проблема с обновлением контроллера массива новыми данными, полученными из запроса сервера.

Настройка

У меня есть объект сущности (назовите его MyParent), который имеет несколько свойств:

name
age
description
widgetID

И объект сущности (назовите его MyWidget), который имеет несколько свойств:

name
size
description

Размер является строковым представлением объекта NSSize. Это облегчает хранение и извлечение из основного хранилища данных и на сервер и обратно в JSON. Чтобы представить размер в пользовательском интерфейсе, я подклассифицировал MyWidget и предоставил пользовательский установщик и получатель в качестве категории пользовательского класса (я сделал это, чтобы XCode не перезаписывал мои изменения, если мне нужно внести изменения в модель ):

-(void)setObjectWidth:(NSInteger)aValue {
    [self setObjectSize:NSMakeSize(aValue, [self objectHeight])];
}

-(void)setObjectHeight:(NSInteger)aValue {
    [self setObjectSize:NSMakeSize([self objectWidth], aValue)];
}

-(void)setObjectSize:(NSSize)aValue {
    [self setSize:NSStringFromSize(aValue)];
}

-(NSInteger)objectWidth {
    return [self objectSize].width;
}

-(NSInteger)objectHeight {
    return [self objectSize].height;
}

-(NSSize)objectSize {
    return NSSizeFromString([self size]);
}

Я получаю widget, выполняя поиск по widgetId в качестве метода категории для родителя:

-(MyWidget *)widget {
    NSManagedObjectContext * moc = [[NSApp delegate] managedObjectContext];

    return [moc fetchObjectForEntityName:@"MyWidget"
                                 withUID:[self widgetID]];
}

fetchObjectForEntityName: withUID - это категория в контексте управляемого объекта.

В пользовательском интерфейсе у меня есть контроллер массива, связанный с tableView MyParent объектов. Выбор объекта представляет детали в пользовательском интерфейсе, которые связаны с соответствующими значениями:

parentArrayController --> parentArray (managed objects in an array)
parentTable --> parentArrayController.arrangedObjects.name

uiWidthTextField --> parentArrayController.selection.widget.objectWidth
uiHeightTextField --> parentArrayController.selection.widget.objectHeight

Контроллер массива отслеживается для изменений, так что он может отключить уведомление для других частей приложения, которые должны знать, что выбранный объект изменился

Что работает

Все работает хорошо. Я могу внести изменения в текстовые поля в пользовательском интерфейсе, и он устанавливает и получает размер от виджета, как вы ожидаете. Добавление родительского элемента - простая задача создания NSURLConnection и отправки соответствующих параметров на сервер. Когда сервер подтверждает добавление, я снова запрашиваю список родительских элементов на сервере.

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

Что сломано

Когда список возвращается, он анализируется правильно, но приложение жалуется, когда обновляется контроллер массива:

Серьезная ошибка приложения. Во время обработки изменения базовых данных возникла исключительная ситуация: невозможно удалить наблюдателя для ключевого пути «widget.objectHeight», поскольку он не зарегистрирован в качестве наблюдателя. with userInfo (null)

Невозможно удалить наблюдателя для ключевого пути "widget.objectHeight", поскольку он не зарегистрирован в качестве наблюдателя.

Что я пробовал

Я попытался добавить willChangeValueForKey: и didChangeValueForKey: обернутый вокруг установщика objectHeight и objectWidth, но, похоже, это не обеспечивает регресс.

Я полагаю, что проблема в том, что IB привязан к widget.objectHeight, а виджет является поиском родительского элемента, а не истинным свойством KVO / KVC. Тем не менее, мне не нужен установщик на widget (хотя я попробую это позже).

Я знаю, что что-то упустил, но не могу на это положить палец.

Мольба

Любая помощь или помощь в решении этой проблемы будет принята с благодарностью!

1 Ответ

0 голосов
/ 13 апреля 2011

Вам необходимо установить objectWidth и objectHeight в качестве немодельных свойств MyWidget.У вас проблемы с KVO, потому что objectWidth и objectHeight не являются ключами MyWidget, а просто имеют имена методов в виде методов получения и установки.

Просто добавьте:

@property() NSInteger objectWidth;
@property() NSInteger objectHeight;

в класс MyWidget, и это должно обеспечить ключи для работы KVO.(Возможно, стоит перепроверить мою форму собственности. Некоторое время мне приходилось писать целочисленное свойство.)

...