问题
I have constructed a view-based NSTableView, programmatically (code-only, without XIB) following this, which is backed by an NSArrayController, created simply by: var controller = NSArrayController()
and bound to the table by:
tableView.bind(NSContentBinding, toObject: controller, withKeyPath: "arrangedObjects", options: nil)
tableView.bind(NSSelectionIndexesBinding, toObject: controller, withKeyPath:"selectionIndexes", options: nil)
tableView.bind(NSSortDescriptorsBinding, toObject: controller, withKeyPath: "sortDescriptors", options: nil)
I only use the controller
's methods to add/remove objects, and get them by: (controller.arrangedObjects as! NSArray)[index]
. The items in the array are of a Class with String?
or dynamic Double
fields and they extend from NSObject
.
Adding and removing rows inside the model automatically adds/removes the corresponding rows in the table, but I cannot bind the cell views to the items -and observe changes in their fields-. I tried to follow this and this with no luck. Final version of my cell view is like:
class PLTextCellView: NSTextField {
init(columnName:String) {
//.... erased...
self.columnName = columnName
}
var columnName = ""
var displayText:AnyObject {
get {
return stringValue
}
set(val) {
stringValue = String(val)
}
}
weak
var item:PLItem? = nil
override
var objectValue: AnyObject? {
didSet {
item = objectValue as? PLItem
if (item != nil) {
Swift.print("item to bind is:\(item) ")
unbind("displayText")
// bind("displayText", toObject: self.item!, withKeyPath: columnName, options: [NSNullPlaceholderBindingOption:"--"])
bind("displayText", toObject: self, withKeyPath: "objectValue."+columnName, options: [NSNullPlaceholderBindingOption:"--"])
} else {
Swift.print("unbinding... ")
unbind("displayText")
}
}
}
deinit {
unbind("displayText")
}
override
func prepareForReuse() {
unbind("displayText")
super.prepareForReuse()
}
///... erased ....
}
If I don't use any binding, I only get item
object ids displayed on the table on each and every column, even if I explicitly set displayText
(so something must be internally setting the text !!)
Question 1: If I use the commented/first bind
line, each item
object prints a different object id to the console -even if some represent the same object- and none of them exist in the controller
! Why ?
Question 2: If I use the uncommented/second bind
line, I get this error: An instance of ...item... was deallocated while key value observers were still registered with it.
. This says I should not do binding/observing in the cell view, but the most convenient place seems the cell view (for MVC). I don't know a way to remove all -view-bindings in the model items in their deinit
s. (Interestingly, I even don't delete any items from the controller
).
As I understand from the related questions and answers, this question also holds for UITableView
's. So, what is the proper way to do the binding ?
来源:https://stackoverflow.com/questions/38047350/what-is-the-proper-way-to-bind-cell-views-to-model-objects-in-nstableview-uita