Search code examples
swiftcocoacocoa-bindings

Change bound variable in Swift class


I have a label with a binding to a variable inside an instance. When I change the variable, I can print out the new content but the label keeps the original content.

class myClass: NSObject {

    var text : String = "Initial"

    override init() {

        text = "Init"
    }

    func change() {
        text = "Changed"
    }
}


@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    var instance = myClass()

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
        instance.change()
        print(instance.text)
    }

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }


}

print(instance.text) gives me "Changed" but the label keeps "Init".

Why does the binding not work in this case?

The label has a "Bind to App Controller" "self.instance.text" binding

Thanks


Solution

  • When Swift APIs are imported by the Objective-C runtime, there are no guarantees of dynamic dispatch for properties, methods, subscripts, or initializers. The Swift compiler may still devirtualize or inline member access to optimize the performance of your code, bypassing the Objective-C runtime.

    You can use the dynamic modifier to require that access to members be dynamically dispatched through the Objective-C runtime. Requiring dynamic dispatch is rarely necessary. However, it is necessary when using using APIs like key–value observing.

    Bindings use key–value observing. Change the text property to dynamic var text : String and var instance to dynamic var instance.