我注意到在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中設計的東西中。
請記住,您可能希望它崩潰,因爲這意味着代碼中存在錯誤。使用選項#2可能會更好,因爲您不需要所有的檢查,並且如果應用程序崩潰(在開發和/或測試過程中,那麼這很好,因爲您在應用程序中發現了一個錯誤)。 – rmaddy
@rmaddy這是一個非常公平的點,我同意。然而,對於發行版,我絕對不想使用選項2.特別是如果您有成千上萬的用戶在使用您的應用程序,您將永遠無法確定會發生什麼情況,將其與項目中的多個開發人員編碼結合在一起,並且讓您頭疼。 – TNguyen
發佈與它有什麼關係?如果您的應用程序已使用選項2進行測試並且工作正常,那麼這是正確的解決方案。如果你釋放它,並且它由於選項2而突然中斷,那麼你做了一個糟糕的工作測試。這仍然是需要修復的代碼中的一個錯誤。這並不意味着使用選項2是錯誤的。 – rmaddy