2017-09-06 65 views
1

我注意到在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!) 

,似乎有與實例變量兩個選項...

  1. 讓他們T?並有guardif let隨處可見。
  2. 使他們v T!,並希望沒有被設置之前調用。

所以也許我的問題歸結爲:在這裏做#2安全嗎?是否有保證在第一個控制器中prepare(for:sender:)之前UIViewController沒有任何內容被調用?

編輯:我不喜歡選項1的一個原因是它幾乎在每種方法中都會導致guards,因爲它們可能是不必要的。看起來像一個代碼味道給我。在純Swift類中,您將通過thingabcinit(...),並且它們是非可選的,但在這裏不能這樣做。我們正在處理一個奇怪的情況,Swift已被添加到Objective C中設計的東西中。

回答

0

理論上講,如果在prepare之前設置所有這些變量,那麼它應該沒問題。但是,使用警衛並讓任何地方都有問題?這只是迅捷的方式。即使現在做數字2是安全的,誰又會說它將來不安全?或者我們不知道的一些奇怪的行爲發生,並且它實際上並不安全,或者您也有其他人在項目中工作,他們不知道這一點,並忘記在繼續之前設置其中一個變量,並且它結束造成事故。因此,1號線是迄今爲止最安全的路線,您可以放心地休息,因爲它知道它不會因此而崩潰。

+3

請記住,您可能希望它崩潰,因爲這意味着代碼中存在錯誤。使用選項#2可能會更好,因爲您不需要所有的檢查,並且如果應用程序崩潰(在開發和/或測試過程中,那麼這很好,因爲您在應用程序中發現了一個錯誤)。 – rmaddy

+0

@rmaddy這是一個非常公平的點,我同意。然而,對於發行版,我絕對不想使用選項2.特別是如果您有成千上萬的用戶在使用您的應用程序,您將永遠無法確定會發生什麼情況,將其與項目中的多個開發人員編碼結合在一起,並且讓您頭疼。 – TNguyen

+1

發佈與它有什麼關係?如果您的應用程序已使用選項2進行測試並且工作正常,那麼這是正確的解決方案。如果你釋放它,並且它由於選項2而突然中斷,那麼你做了一個糟糕的工作測試。這仍然是需要修復的代碼中的一個錯誤。這並不意味着使用選項2是錯誤的。 – rmaddy