Refresh Cocoa-Binding - NSArrayController - ComboBox

≯℡__Kan透↙ 提交于 2019-12-21 20:33:42

问题


in my application I made a very simple binding. I have a NSMutableArray bound to a NSArrayController. The controller itself is bound to a ComboBox and it shows all the content of the NSMutableArray. Works fine.

The problem is : The content of the Array will change. If the user makes some adjustments to the app I delete all the items in the NSMuteableArray and fill it with new and different items.

But the binding of NSMutableArray <-> NSArrayController <-> NSComboBox does not refresh.

No matter if I remove all objects from the Array the ComboBox still shows the same items.

What is wrong here? Is my approach wrong or do I only need to tell the binding to refresh itself? I did not find out how to do that.


回答1:


You're likely "editing the array behind the controller's back", which subverts the KVO mechanism.

You said:

I have a NSMutableArray bound to a NSArrayController.

How? Where does the array live? In a document, accessible via a KVC/KVO compliant -myArray / -setMyArray: set of accessors?

I'll bet you're directly telling the "myArray" ivar to -removeAllObjects, right? How will these KVC/KVO accessors "know" the array has changed?

The answer is, they don't. If you're really replacing the whole array, you'll want to tell your document (or whoever owns the array) to -setMyArray: to a whole new array. This will trigger the proper KVO calls.

... but then, you don't really need a mutable array, do you? If you only want to replace individual items in the array, you'll want to use indexed accessors:

(Documentation - see the Collection Accessor Patterns for To-Many Properties section) http://tinyurl.com/yb2zkr5




回答2:


Try this (using ARC/OS X 10.7):

in header file, define the arrayInstance and the arrayController

 @property (weak) IBOutlet NSArrayController *arrayController;
 @property (strong) NSArray *arrayInstance; // for the array instance

then in implementation

 @synthesize arrayController = _arrayController;
 @synthesize arrayInstance = _arrayInstance;

 _arrayInstance = .......  // What ever the new array will be
 [_arrayController setContent:_arrayInstance];

This will force the arrayController to update the content and display correctly.

Another but 2 line of code solution would be:

 [self willChangeValueForKey:@"arrayInstance"];
 _arrayInstance = .......  // What ever the new array will be
 [self didChangeValueForKey:@"arrayInstance"];

Think the first looks more obvious, the second more KVO-like.




回答3:


KVC/KVO compliance seems to be the problem. You should create the new array and update the reference with the new object by using the generated accessor methods. You may otherwise fire KVO messages about the array being updated to inform the bindings, that the contents of the array have changed.

Christian



来源:https://stackoverflow.com/questions/1623396/refresh-cocoa-binding-nsarraycontroller-combobox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!