Ручная привязка какао не изменяется Observed KeyPath - PullRequest
5 голосов
/ 07 июля 2011

Я изменяю привязку какао программно.Я связываю значение 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... };
}

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

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 Ответ

0 голосов
/ 07 февраля 2014

Как указывал @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 мягко не рекомендуется.

...