NSObject perform Selector get wrong result

public class A {
    
    public var target: NSObject
    public var action: Selector
    
    public init(target: NSObject, action: Selector) {
        self.target = target
        self.action = action
    }
    
    public func call() {
        self.target.perform(action, with: 1)
    }
}

public class B : NSObject {
    
    public var a: A!
    
    public override init() {
        super.init()
        a = A.init(target: self, action: #selector(handler(value:)))
    }
    
    @objc func handler(value: Int) {
        print("handle callback: \(value)")
    }
}


let b = B.init()
b.a.call() // handle callback: -2069308530273730897

Hi, All:
as shown above, the @objc function gets called with a parameter 1, but the print result is different, what's wrong with this?

If I’m not mistaken, perform is an Objective-C function that takes an id for the with parameter, so Swift is wrapping the 1 in a NSValue object before calling it. What you’re getting is probably the address of that object.
Try to change handler’s value parameter type to Any and see if that works better. (Note that #selector doesn’t carry type information so the compiler can’t detect type mismatches)

1 Like

Thank you, once I update the code as below, it returns the correct value!

    @objc func handler(value: Any) {
        if let a = value as? Int {
            print("handle callback: \(a)")
        }
    }