如何避免Swift UIViewControllers中的可选检查?
问题描述:
我注意到在iOS代码中有一个烦人的模式。在新的视图控制器被实例化之后,视图控制器被传递来自先前的视图控制器的参数,所以最终得到如下例子的代码。 SecondViewController
的属性实际上不是可选的,但它们必须是可空的,因为您将它们设置为prepare(for:sender:)
。如何避免Swift UIViewControllers中的可选检查?
class FirstController : UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
...
let vc = segue.destination as! SecondController
vc.thing = getThing()
vc.abc = "123"
...
class SecondController : UIViewController {
var thing: Thing?
var abc: String?
override func viewDidLoad() { ... }
func foo() {
guard let thing = self.thing else { return }
...
}
func bar() {
blahBlah(abc!)
,似乎有与实例变量两个选项...
- 让他们
T?
并有guard
或if let
随处可见。 - 使他们v
T!
,并希望没有被设置之前调用。
所以也许我的问题归结为:在这里做#2安全吗?是否有保证在第一个控制器中prepare(for:sender:)
之前UIViewController
没有任何内容被调用?
编辑:我不喜欢选项1的一个原因是它几乎在每种方法中都会导致guards
,因为它们可能是不必要的。看起来像一个代码味道给我。在纯Swift类中,您将通过thing
和abc
到init(...)
,并且它们是非可选的,但在这里不能这样做。我们正在处理一个奇怪的情况,Swift已被添加到Objective C中设计的东西中。
答
理论上讲,如果在prepare之前设置所有这些变量,那么它应该没问题。但是,使用警卫并让任何地方都有问题?这只是迅捷的方式。即使现在做数字2是安全的,谁又会说它将来不安全?或者我们不知道的一些奇怪的行为发生,并且它实际上并不安全,或者您也有其他人在项目中工作,他们不知道这一点,并忘记在继续之前设置其中一个变量,并且它结束造成事故。因此,1号线是迄今为止最安全的路线,您可以放心地休息,因为它知道它不会因此而崩溃。
请记住,您可能希望它崩溃,因为这意味着代码中存在错误。使用选项#2可能会更好,因为您不需要所有的检查,并且如果应用程序崩溃(在开发和/或测试过程中,那么这很好,因为您在应用程序中发现了一个错误)。 – rmaddy
@rmaddy这是一个非常公平的点,我同意。然而,对于发行版,我绝对不想使用选项2.特别是如果您有成千上万的用户在使用您的应用程序,您将永远无法确定会发生什么情况,将其与项目中的多个开发人员编码结合在一起,并且让您头疼。 – TNguyen
发布与它有什么关系?如果您的应用程序已使用选项2进行测试并且工作正常,那么这是正确的解决方案。如果你释放它,并且它由于选项2而突然中断,那么你做了一个糟糕的工作测试。这仍然是需要修复的代码中的一个错误。这并不意味着使用选项2是错误的。 – rmaddy