问题
I'm showing the contents of an array of strings with an NSTableView via binding through an Array Controller.
I have "NSString" in Class Name in the attributes inspector for the Array Controller and in the Model Key Path of the Array Controller's binding inspector I have the path to my array. And I have the only column of the table bound in its Value section to the Array Controller without Model Key Path specified (it's just an array of strings).
As a result, the array's strings are displayed fine in the table. But I can't edit any of the rows:
2015-06-17 15:48:44.285 ProjectName[9043:123132] An uncaught exception was raised
2015-06-17 15:48:44.285 ProjectName[9043:123132] Error setting value for key path of object five (from bound object <NSTableColumn: 0x618000082d50> identifier: (null)): [<Swift._NSContiguousString 0x608000045d60> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key .
"five" is the fifth string in the array that I was trying to edit. And as you can see there is a gap in "path of" because the Model Key Path is empty for the column's values.
So do I somehow refer to the string itself in the Model Key Path to make the array editable via the table?
回答1:
The Class Name should absolutely be set to a valid class. The bigger problem is that the array controller doesn't really play nicely with arrays of strings. There's no (reasonable) way to use -setValue:forKey:
on a string since the string is itself what's being edited (replaced), not some property (like "displayName
").
I know it seems wasteful, but if you really must use an array controller (more on that in a moment), you should just create a class with a string property and set that as the controller's class name and maintain an array of that class instead of plain strings. Say your array of strings represents tags. Make a Tag
class with a name
property of type String
(or NSString
). Set your controller's class name to Tag
. This way, there's a key path to which to bind.
But if you really don't see yourself needing anything but an array of strings, you could just use the standard (and infinitely more flexible) [NSTableViewDataSource][1]
protocol and good old-fashioned actions triggered by buttons (like Add and Remove). This way you're not fighting the Cocoa Bindings / KVC / KVO mechanisms for what in this case amounts to too-primitive a type (string) for a very abstract controller.
As to amount of work, it's almost "six of one half-dozen of the other" but not quite -- I'd go with the "make it a class with a name property" route for two reasons: 1) It's less work than spinning up a whole table controller / data source, and 2) It's likely you'll later wish you had a more extensible class instead of a simple string for a "list of stuff" even if you don't think so now.
来源:https://stackoverflow.com/questions/30892315/binding-an-nstableview-to-an-array-of-strings-in-swift