从Objective-C调用带URL参数的Swift方法报错:找不到对应选择器
看起来你遇到的是Swift与Objective-C交互时方法签名不匹配的典型问题,我来帮你一步步排查:
1. 确认方法类型:类方法 vs 实例方法
你在Objective-C中用[URLTask primer];直接通过类调用方法,说明你的Swift中的primer()必须是类方法(标记为class func),而不是普通的实例方法。所以你的ladeURL(url:)也需要改成类方法,否则Objective-C中需要先创建实例才能调用。
修正后的Swift方法定义:
@objc public class func ladeURL(url: URL?) { print("loadURL") }
2. 处理Swift方法到Objective-C的签名转换
Swift 3+中,带参数的方法暴露给Objective-C时,默认会把第一个参数名整合到selector中。比如你的ladeURL(url:)方法,在Objective-C中对应的selector是ladeURLWithUrl:,而不是你写的ladeURL:。
所以你可以直接修改Objective-C的调用代码:
NSURL* testURL = [NSURL URLWithString:@"http://www.google.com"]; [rURLTask ladeURLWithUrl:testURL]; // 注意这里的方法名是ladeURLWithUrl:
3. 自定义Objective-C方法名(可选)
如果你希望在Objective-C中保持ladeURL:的调用方式,可以用@objc()标记来指定方法的Objective-C名称:
@objc(ladeURL:) public class func ladeURL(url: URL?) { print("loadURL") }
这样你原来的Objective-C调用代码[URLTask ladeURL:testURL];就能正常工作了。
4. 检查Swift类的Objective-C暴露名称
报错信息里提到的是rURLTask,但你在Objective-C中用的是URLTask,这说明你可能没有给Swift类指定Objective-C别名。如果想让Objective-C中用URLTask作为类名,需要在Swift类上添加@objc(URLTask)标记:
@objc(URLTask) public class rURLTask: NSObject { @objc public class func primer() { print("primer") } @objc(ladeURL:) public class func ladeURL(url: URL?) { print("loadURL") } }
按照上面的步骤调整后,你的带参数方法应该就能在Objective-C中正常调用了。
内容的提问来源于stack exchange,提问作者heimi

