在简短教程here中,在步骤5中分配了一个代理:
if let nav = segue.destination as? UINavigationController,
let classBVC = nav.topViewController as? ClassBVC {
// 'self' is ClassAVC which has been delegated.
classBVC.delegate = self
}
我发现很难遵循这些陈述,所以写下来是一个很大的缺点:
let nav = segue.destination as? UINavigationController
let classBVC = nav?.topViewController as? ClassBVC
classBVC!.delegate = self
答案 0 :(得分:3)
没有顺序绑定这样的东西。你在第二个语句中所做的是被称为可选链接和可选的强制转换,如果不是你最后一行中的强制解包,这将是安全的。
此处展开的力量使您的第二个解决方案不安全。如果任何先前的可选操作导致nil
值,则将发生运行时异常。
classBVC!.delegate = self
如果需要打开可选值,可选绑定是执行此操作的最佳选项之一。您可以通过减少if let
语句的数量来使可选展开的样板代码最小化。在某些情况下,使用guard let
代替if let
也可以生成更清晰的代码,因为您不必将块嵌套在彼此内部。
使用可选绑定,您将永远不会看到
在展开可选值时意外发现nil
运行时异常,如果您强行解包可能实际具有nil
值的选项,您可能会经常看到它。
guard let nav = segue.destination as? UINavigationController, let classBVC = nav.topViewController as? ClassBVC else { return }
classBVC.delegate = self
答案 1 :(得分:1)
是的,因为您声明classBVC
绝对是ClassBVC
个对象。如果你将它包装在if let
语句中,如果一个失败,它将不会崩溃展开nil值。
答案 2 :(得分:1)
如果您的应用成功运行需要ClassBVC
成为destination
导航控制器的顶视图控制器,那么您的第二个模式没有任何问题。事实上,我实际上更喜欢你的第二个模式,因为使用前一个模式(可选的强制转换/解包),如果任何一个强制转换失败,代码会默默地进展,而不会让你知道出现了严重的问题。而你正在努力弄清楚为什么没有调用你的委托方法。
我可能会建议的唯一一个小调整是,如果这确实是要求,我会完全删除可选的投射/链接。如果前两行可选的转换/链接中的任何一行失败,则有两行可选的转换/链接,然后是强制解包,这将无效。我会在代码中明确说明:
let nav = segue.destination as! UINavigationController
let classBVC = nav.topViewController as! ClassBVC
classBVC.delegate = self
这样,在阅读你的代码时,你不必到第三行来确定前两个强制转换不是真正可选的,而是必不可少的。这一修订明确了这一点。
如果您感到被迫guard
对抗其中一个演员阵容可能失败的情况,我建议您确认通知开发人员这些必要的(假设他们是真正需要的)演员表失败:
guard let nav = segue.destination as? UINavigationController, let classBVC = nav.topViewController as? ClassBVC else {
fatalError("destination should be nav controller who's top view controller is a ClassBVC")
}
classBVC.delegate = self
我个人认为这比上面的模式要好得多(当然,错误更明确,但我不认为代码更具可读性和结果,如果转换失败则崩溃,是相同)。但是如果你想要一个更具信息性的错误信息,那就是解决这个问题的一种方法。