Swift 4计算器点击按钮报unrecognized selector错误排查求助
解决Swift 4升级后按钮点击"unrecognized selector"错误
这个问题我之前升级Swift版本的时候也碰到过,核心原因是Swift 2到Swift 4的方法签名映射规则变了,导致Storyboard里的按钮连接找不到对应的方法。
第一步:修正IBAction的方法签名
你的代码里的两个IBAction方法签名在Swift 4里不符合Objective-C的selector匹配规则,这是触发错误的直接原因,需要修改:
原来的代码:
@IBAction func numberTapped(sender: AnyObject) { // ... } @IBAction func resetCalculator(sender: AnyObject) { // ... }
改成:
@IBAction func numberTapped(_ sender: UIButton) { // ... } @IBAction func resetCalculator(_ sender: UIButton) { // ... }
为什么要这么改?
- 在Swift 2中,
func numberTapped(sender: AnyObject)会被Objective-C识别为numberTappedWithSender:这个selector;但在Swift 4中,如果没有下划线_,方法会被映射成numberTapped(sender:),而Storyboard里的按钮连接还是沿用了旧的selector,导致系统找不到对应的方法,抛出"unrecognized selector"错误。 - 把
AnyObject改成UIButton更安全,也符合Swift的类型推断,避免不必要的类型转换。
第二步:检查其他Swift 4迁移细节(避免后续问题)
除了selector的问题,你的代码里还有一些Swift 2到Swift 4的适配点,建议一起修正:
- URLRequest替代NSMutableURLRequest:Swift 4推荐使用原生的
URLRequest,而不是NSMutableURLRequest,可以修改网络请求部分:let url = URL(string: "https://api.fixer.io/latest?symbols=PLN&base=EUR")! var request = URLRequest(url: url) request.cachePolicy = Reachability.isConnectedToNetwork() ? .useProtocolCachePolicy : .returnCacheDataElseLoad request.timeoutInterval = .infinity - JSON解析逻辑错误:Fixer.io的返回是一个字典,不是数组
[[String: String]],你的解析代码会导致valutas数组为空,后续访问valutas[0]会崩溃,应该改成:if let json = try JSONSerialization.jsonObject(with: data!) as? [String: Any] { let valuta = ValutaWaarde(dictionary: json as NSDictionary) self.valutas.append(valuta!) } - NSString转Float的优化:Swift 4里可以直接用
Float(euro.text!),不需要转成NSString:output = Float(euro.text!)! * Float(valutas[0].rates?.pLN ?? 0)
最后验证
修改完方法签名后,建议重新连接一下Storyboard里的按钮(或者直接Clean项目后重新编译),确保按钮的IBAction连接指向修改后的方法。
内容的提问来源于stack exchange,提问作者Sinan Samet
相关产品推荐
相关产品推荐

