Xcode 10.2(Swift 5.0编译器)协议继承问题求助
我之前在Xcode 10.2版本开发时,碰到过和你完全一致的问题!当时折腾了好久才找到根源和解决办法,分享给你:
问题根源
这是Xcode 10.2自带的Swift编译器的协议继承识别bug。当父类已声明遵守UITableViewDataSource/UITableViewDelegate,子类仅继承父类时,编译器在首次clean编译、归档打包的场景下,无法正确识别子类自动继承了这些协议,导致子类中实现的代理方法无法被tableView正确关联调用。而第二次编译时,因为有缓存,编译器又能正常识别,就出现了“首次运行失败,之后正常”的诡异现象。
可行的解决办法
1. 主动声明子类的协议遵守(忽略冗余警告)
虽然编译器会提示“Redundant conformance to protocol 'UITableViewDataSource'”这类警告,但你可以在子类的类声明里显式加上协议:
class ExampleViewController: BasicViewController, UITableViewDataSource, UITableViewDelegate { // 子类逻辑 }
然后在项目的Build Settings中,搜索Redundant conformance protocol,将对应的警告级别改为None,就能消除这个冗余提示。这个方法能强制编译器识别子类的协议身份,确保代理方法被正确绑定。
2. 在子类中手动重置tableView的代理
在子类的viewDidLoad或viewWillAppear中,手动重新设置一次tableView的dataSource和delegate为self:
override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self }
虽然你说已经设置正确,但编译器bug可能导致初始的关联失效,手动重置能绕过这个问题。
3. 升级Xcode版本(彻底解决)
这个bug在Xcode 10.3及后续版本中已经被苹果修复了。如果项目允许的话,直接升级到更高版本的Xcode,就能彻底解决这个协议继承的问题,不用再做临时规避。
额外提示
如果你的父类中有部分代理方法是默认实现,子类重写时一定要加上override关键字,这也能帮助编译器更准确地识别方法归属,减少这类诡异问题的出现。
内容的提问来源于stack exchange,提问作者o15a3d4l11s2

