在扩展程序中定义的递归函数中访问self
时,我遇到意外的EXC_BAD_ACCESS错误。
我已将设置的复杂性降低到一个简单的(ish)示例,该示例仍然展示了该问题。我有一个ThemeableViewController
协议和一个协议扩展,它定义了一个函数实现(cascaseInitialise(withTheme)
):
protocol ThemeableViewController where Self: UIViewController { }
extension ThemeableViewController {
func cascadeInitialise(withTheme theme: Theme) {
// will perform other initialisation here; excluded for testing
if let tabVC = self as? UITabBarController, let innerVCs = tabVC.viewControllers {
for themableVC in innerVCs.flatMap({$0 as? ThemeableViewController}) {
themableVC.cascadeInitialise(withTheme: theme)
}
}
}
}
我使用了扩展来使其他UIViewController
类符合此协议:
extension UITabBarController: ThemeableViewController { }
extension UISplitViewController: ThemeableViewController { }
我的根视图控制器是UITabBarController
;它的4个视图控制器都是UISplitViewController
个。我在我的根视图控制器上调用cascadeInitialise
,如下所示:
let rootTabBarVC = UIApplication.shared.delegate!.window!!.rootViewController as! UITabBarController
rootTabBarVC.cascadeInitialise(withTheme: .normal)
在cascadeInitialise
的第二次调用中(即当self
为UISplitViewController
时),我发现if let tabVC
行上的EXC_BAD_ACCESS崩溃}。请参阅以下堆栈跟踪:
奇怪的是,在调试时,如果我在该行上放置一个断点,在控制台中输入po self as? UITabBarController
not 会导致错误(它会按预期返回{{ 1}}):
我无法解决这里的问题。