Reputation: 305
I'm trying to use cocoa bindings with nstableview and I have some problems with bind of parameter value of textfield:
I'm using this code, class:
class Person : NSObject {
var givenName:String
var familyName:String
var age = 0
var lol = 0
override init() {
givenName = "given"
familyName = "family"
lol = 36
super.init()
}
init(givenName:String, familyName:String, age:Int) {
self.givenName = familyName
self.familyName = givenName
self.age = age
self.lol = 36
super.init()
}
and view controller:
class ViewController: NSViewController {
@IBOutlet weak var tableViewL: NSTableView!
@IBOutlet var superResultsController: NSArrayController!
@objc dynamic var array = [Person]()
override func viewDidLoad() {
super.viewDidLoad()
array.append(Person(givenName: "sas", familyName: "gfg", age: 10))
array.append(Person(givenName: "sddsgds", familyName: "gfg", age: 10))
array.append(Person(givenName: "uoijh", familyName: "gfg", age: 10))
print(superResultsController.arrangedObjects)
}
I found that I can't bind textfield to any variable of my class - app crashes with bad_instruction error.
Here's my bindings of array controller and table view: NSArrayController:
Upvotes: 2
Views: 881
Reputation: 2419
Cocoa Bindings are built on top of KVO. And KVO uses isa swizzling to insert hooks for automatic KVO notifications.
You have to mark those properties as dynamic so that the compiler doesn't optimize the calls to those properties. Making sure that, at runtime, getting/setting those properties will always flow through instance methods is essential for the KVO machinery to work.
Not marking those fields as dynamic might appear to work. When bindings are setup at runtime, the textfield will explicitly call the property to get the initial value to display. But any changes made to those properties will not send a KVO notification and the textfield will not update.
If you want to properly test this, add this code to the end of viewDidLoad
:
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.array[0].givenName = "Some Name"
NSLog("Changed the name")
}
Run once, see that the table view doesn't update when the name changes. Add the dynamic
to givenName
on Person
and run again, verify the table view updates.
Upvotes: 4