Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why delegate.respondsToSelector (Selector ("testEnum:")) this code will return false in swift language?

I was a few days ago from Objective-C to write Swift language, in the project I have encountered a problem.This problem is when using respondsToSelector ("testEnum:") function to check whether to implement the function of the testEnum:,if the param is the case, it will return false, I have tried other types, it will return true, do not know what is the reason, see the following code, to help me solve it, thank you very much!

 enum TestEnum {
        case A
        case B
        case C
    }

    protocol TestAProtocol: NSObjectProtocol {
        func testEnum(testEnum: TestEnum);
        func testInt(testInt: Int);
    }

    class TestA: NSObject {
        var delegate: TestAProtocol?;

        func executeDelegateCallBack() {
            if (delegate != nil && delegate!.respondsToSelector(Selector("testEnum:"))) { // delegate!.respondsToSelector(Selector("testEnum:")) return false ?
                delegate?.testEnum(TestEnum.A);
            }

            if (delegate != nil && delegate!.respondsToSelector(Selector("testInt:"))) { // delegate!.respondsToSelector(Selector("testInt:")) return true ?
                delegate?.testInt(0);
            }
        }
    }

    class TestB: NSObject, TestAProtocol {
        func initTestB () {
            let testA: TestA = TestA();
            testA.delegate = self;
            testA.executeDelegateCallBack();
        }

        // mark TestAProtocol
        func testInt(testInt: Int) {

        }

        func testEnum(testEnum: TestEnum) {

        }
    }
like image 392
fly_basket Avatar asked Feb 27 '26 21:02

fly_basket


1 Answers

respondsToSelector() uses the Objective-C runtime and works only with methods which are Objective-C compatible. Swift enums can only be represented in Objective-C if they are marked with @objc, and that requires that they have an integer raw value.

So with

@objc enum TestEnum : Int {
    case A
    case B
    case C
}

your respondsToSelector(Selector("testEnum:") will return true.

Note however that testing for the presence of a method makes only sense with optional protocol methods, and these are only available for @objc protocols, for example:

@objc enum TestEnum : Int {
    case A
    case B
    case C
}

@objc protocol TestAProtocol: NSObjectProtocol {
    optional func testEnum(testEnum: TestEnum)
    func testInt(testInt: Int)
}

And then it is much simpler to use optional chaining instead of respondsToSelector:

func executeDelegateCallBack() {
    delegate?.testEnum?(.A)

    // ...
}

or more detailed:

func executeDelegateCallBack() {
    if let testEnum = delegate?.testEnum {
        testEnum(.A)
    } else {
        print("delegate is `nil` or does not respond to `testEnum`")
    }

    // ...
}
like image 193
Martin R Avatar answered Mar 02 '26 13:03

Martin R



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!