Ручная привязка какао не изменяется Наблюдаемый 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 мягко осуждаются.