我们常常会在派生类实例的override方法里调用其super同名方法,这很常见,比如:
class ViewController:UITableViewController{ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { super.tableView(tableView, didSelectRowAt: indexPath) //Will Crash!!! }
你知道上面那句super.xxx方法调用会发生什么吗???
注释里已经给出答案了:你的App会不给任何情面的崩掉 ;(
你可能不会相信!?请你实际试一下哦.
之所以会崩溃的原因就在于tableView(_:didSelectRowAt:)虽然是超类的重载方法,但它是定义在UITableView协议里的,而碰巧这个协议方法是可选的!!!
不信?你可以尝试在以下方法中调用super:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
不会有任何问题!虽然这很傻…
因为上面的方法是一个必选方法!
回到最初的例子,解决方法是你不需要在tableView(_:didSelectRowAt:)调用super,因为超类根本就没有实现它!!!
不过,如果你很执着的要想调用super怎么办呢?
你可能会尝试用以下代码先判断该方法是否存在,如果存在则调用:
if super.responds(to: #selector(super.tableView(_:didSelectRowAt:))){ super.tableView(tableView, didSelectRowAt: indexPath) }
不过遗憾的是,该判断总是返回true,你还是会挂…
正确的方法是在super类中判断:
if super.superclass!.instancesRespond(to: #selector(tableView(_:didSelectRowAt:))){ super.tableView(tableView, didSelectRowAt: indexPath) }
that’s all!!! ;)