Ручная привязка какао не изменяется Наблюдаемый KeyPath

Я изменяю привязку какао программно. Я связываю значение NSTextField с выбором ArrayController. После того, как я вручную изменил привязку, я получаю сообщение об ошибке "не соответствует ключу-значению для ключа..", причем ключом является старый ключ, а не новый.

Проверьте код:

NSTextField *textField = [self listTextField];   

NSDictionary *currentBindInfo = [textFieldTableViewCell infoForBinding:NSValueBinding];
NSLog(@"pre-change bindings for textField: %@", currentBindInfo);

/* Change the binding.  [Tried unbind: first, no difference] */
[textField bind:NSValueBinding
                      toObject:[currentBindInfo valueForKey:NSObservedObjectKey] 
                   withKeyPath:@"objectValue.iLifeProductName"
                       options:[currentBindInfo valueForKey:NSOptionsKey]];

/* Log the info so we can confirm it changed. debugging. */
NSLog(@"post-change bindings for textField: %@", [textFieldTableViewCell infoForBinding:NSValueBinding]);

Чтобы устранить неполадки, я вызываю "infoForBinding" до и после изменения, и оно выглядит корректным. Я могу увидеть старое значение, затем я вызываю bind: toObject... и снова выкидываю infoForBinding, и значение для привязки изменилось:

2011-07-06 22:36:23.137 My App 2011[14640:407] pre-change bindings for listTextFieldTableViewCell: {
NSObservedKeyPath = "selection.osxProductName";
NSObservedObject = "...sameTextField... 0x4009cc380>";
NSOptions =     {...same... };
}

2011-07-06 22:36:23.138 My App 2011[14640:407] post-change bindings for listTextFieldTableViewCell: {
NSObservedKeyPath = "selection.iLifeProductName";
NSObservedObject = "...sameTextField... 0x4009cc380>";
NSOptions =     {...same... };
}

Но код все еще вызывает исходный ключ:

2011-07-06 22: 36: 23.231 My App 2011 [14640: 407] [valueForUndefinedKey:]: сущность ILifeVersion не совместима со значением кода для ключа "osxProductName".

-

NSArrayController привязан к ManagedObjectContext, имя объекта изменяется ранее с помощью этого:

  [[self listAC] setEntityName:entityName];

Кэшируется ли оригинальный keyValuePath где-то, что мне нужно очистить? Есть ли сообщение наподобие willChange/didChangeValueForKeyValuePath, которое мне нужно отправить в связывание или arrayController, когда я изменяю наблюдаемый путь ключа?

Идеи?

Спасибо!

1 ответ

Как заметил @noa, вы смотрите на привязку к ячейке, но изменяете привязку для ее элемента управления. Это обязано (гм) вызывать проблемы.

Заменить это:

[textField bind:NSValueBinding
                  toObject:[currentBindInfo valueForKey:NSObservedObjectKey] 
               withKeyPath:@"objectValue.iLifeProductName"
                   options:[currentBindInfo valueForKey:NSOptionsKey]];

с этим:

[textFieldTableViewCell bind:NSValueBinding
                  toObject:[currentBindInfo valueForKey:NSObservedObjectKey] 
               withKeyPath:@"objectValue.iLifeProductName"
                   options:[currentBindInfo valueForKey:NSOptionsKey]];

И посмотри, работает ли он лучше.


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

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

Это означает, что если в XIB вы связываетесь с одной или другой вещью, это хорошо. Это также означает, что вы можете привязать к ячейке в случаях, когда у вас есть несколько ячеек на просмотр, так что это хорошо. ОДНАКО, это может привести к путанице, потому что на самом деле вы можете на самом деле связать как свою точку зрения, так и ее ячейку, и на самом деле связать их по-разному, и тогда они столкнутся.

В вашем примере, я полагаю, вы добавляете вторую привязку к NSControl в дополнение к привязке на его NSCell. Вы связаны дважды. Это не хорошо.

С точки зрения наилучшей практики, я стараюсь привязывать только к NSControls, если у меня нет веских причин переходить на NSCells. Отчасти потому, что это соответствует тому, что я делаю в XIB, отчасти потому, что любой стандарт помогает решить именно эту проблему, а отчасти потому, что NSCells мягко осуждаются.

Другие вопросы по тегам