skip to Main Content

I’m binding NSValueTransformer programatically to NSTextField property on demand in a macOS application. My question is how can I remove this binding?

Relevant code snippet to bind the NSValueTransformer:

@IBOutlet var plcAddrLabel: NSTextField!

@objc dynamic var registerAddr = Int(1)

var optionsDict: [NSBindingOption : Any] = [:]

optionsDict = [NSBindingOption.valueTransformer:decToHexTransformer(), NSBindingOption.valueTransformerName:NSValueTransformerName.decToHexTransformerName]
            
plcAddrLabel.bind(.value, to: self, withKeyPath: "plcRegisterAddress" , options: optionsDict)

When it comes to unbinding I have tried a number of different approaches:

The following code

optionsDict = [NSBindingOption.valueTransformer: "<null>", NSBindingOption.valueTransformerName: "<null>"]
plcAddrLabel.bind(.value, to: self, withKeyPath: "plcRegisterAddress" , options: optionsDict)

causes this error upon execution:

-[NSTaggedPointerString transformedValue:]: unrecognized selector sent to instance 0x7b73031cc07cbe65

The reason for using "<null>" is that it is returned by plcAddrLabel.infoForBinding(.value) before binding the NSValueTransformer for the first time:

NSValueTransformer = "<null>";

NSValueTransformerName = "<null>";

I have also tried

optionsDict = [NSBindingOption.valueTransformer: NSBindingOption.nullPlaceholder, NSBindingOption.valueTransformerName: NSBindingOption.nullPlaceholder]

unfortunately the result is the same.

Interestingly plcAddrLabel.infoForBinding(.value) also shows:

NSNullPlaceholder = "<null>";

It appears, as soon as I try to remove/clear the transformer option the transformer gets called.

Note: while the transformer is bound to the NSTextfield it works fine. Replacing one transformer with another transformer also works.

Any suggestions for further diagnosis would be much appreciated.

Xcode 13.2.1

2

Answers


  1. I assume you wanted this

    plcAddrLabel.unbind(.value)
    
    Login or Signup to reply.
  2. I think you’re looking or NSObject.unbind(_:)

    It appears, as soon as I try to remove/clear the transformer option the transformer gets called. Note: while the transformer is bound to the NSTextfield it works fine.

    Could you elaborate on this?

    The following code

    optionsDict = [NSBindingOption.valueTransformer: "<null>", NSBindingOption.valueTransformerName: "<null>"]
    plcAddrLabel.bind(.value, to: self, withKeyPath: "plcRegisterAddress" , options: optionsDict)
    

    causes this error upon execution:

    Of course it does! "<null>" is just a string, with absolutely no special semantic value in this context. It’s not an NSValueTransformer, and doesn’t respond to the transformedValue message.


    Side note, this code doesn’t make much sense:

    var optionsDict: [NSBindingOption : Any] = [:]
    
    optionsDict = [NSBindingOption.valueTransformer:decToHexTransformer(), NSBindingOption.valueTransformerName:NSValueTransformerName.decToHexTransformerName]
                
    plcAddrLabel.bind(.value, to: self, withKeyPath: "plcRegisterAddress" , options: optionsDict)
    

    You’re making an empty dictionary to assign to optionsDict, but you’re then immediately replacing it with a new dictionary. This causes it to be needless mutable. It could just be:

    let optionsDict: [NSBindingOption : Any] = [
        NSBindingOption.valueTransformer: decToHexTransformer(),
        NSBindingOption.valueTransformerName: NSValueTransformerName.decToHexTransformerName
    ]
    
    plcAddrLabel.bind(.value, to: self, withKeyPath: "plcRegisterAddress" , options: optionsDict)
    

    Better yet, if you inlined it, the type and used some implicit member expressions, it gets even nicer:

    plcAddrLabel.bind(.value, to: self, withKeyPath: "plcRegisterAddress" , options: [
        .valueTransformer: decToHexTransformer(),
        .valueTransformerName: NSValueTransformerName.decToHexTransformerName
    ])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search