2017-08-07 66 views
3

由於viewdidload()僅在UIViewController對象的實例的生命週期中被調用一次,是否意味着下面的這個例子是一個「不好的做法」,因爲setBackgroundColor()是一個只調用一次的函數,無需加載當它真的應該完全存在(定義和調用)在viewdidload()內部時,它們進入整個類的內存中?或者就效率而言,setBackgroundColor()是在哪裏定義和調用的?定義函數裏面的viewdidload()比外部定義它們更節省內存嗎?

class MasterViewController: UIViewController { 

    func setBackgroundColor() { 
     self.view.backgroundColor = UIColor.green 
    } 

    // Do any additional setup after loading the view, typically from a nib. 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     setBackgroundColor() 

    } 

    // Dispose of any resources that can be recreated. 
    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

} 

回答

2

這不是內存使用的情況下,它的有效負載的觀點的問題。

UIViewControllers控制視圖。但視圖不是與視圖控制器同時創建的。

viewDidLoad中設置背景顏色的確是任何視圖配置,因爲調用該方法時,視圖已在視圖控制器生命週期中的一個方便點創建(儘管未必顯示)。如果你創建了視圖控制器,然後調用你的方法,調用的self.view部分將導致視圖直接創建,如果它尚未被創建。

對於某些方法(如視圖控制器演示),這允許創建方法儘可能快地返回,而不會立即加載視圖並保持UI的響應。

這是因爲UIViewController具有isViewLoaded參數的延遲加載,該參數返回一個布爾值,判斷視圖是否加載到內存中,但不會導致視圖加載。

2

我在代碼中沒有看到任何可以保證內存的問題。微型優化是軟件開發中最大的浪費時間。但是既然你問了,viewDidLoad只被調用一次。從蘋果公司的Work with View Controllers

創建和故事板加載視圖控制器的內容視圖(其視圖層次結構的頂部)時viewDidLoad() -Called。視圖控制器的插座在調用此方法時保證具有有效值。使用此方法執行視圖控制器所需的任何其他設置。

通常情況下,iOS只在第一次創建內容視圖時調用viewDidLoad()一次;但是,當控制器第一次實例化時,不一定會創建內容視圖。相反,它在系統或任何代碼第一次訪問控制器的視圖屬性時被延遲創建。

+0

該文檔稱「使用此方法執行視圖控制器所需的任何其他設置」,但將背景色設置爲「附加設置」?它不是主要的,基礎設置? func在不在viewdidload()內部時不加載,這導致我相信「附加設置」的措辭有點誤導。是? –

+0

認識到viewController與視圖不同是很重要的。您正在設置視圖的顏色,它是viewController設置的一部分。 – toddg

3

對一個方法進行本地化的函數改變了它的範圍,但不是它編譯的代碼的生命週期。類的方法也一樣:它們的二進制代碼不是單獨管理的,至少目前不是。不過,這並不是什麼大問題,因爲你的函數的可執行代碼相對較小。

這裏重要的是,該功能的名稱不是在其外部範圍可見,讓其他方法定義無關自己setBackgroundColor()功能內viewDidLoad定義的:

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Nested function definition 
    func setBackgroundColor() { 
     self.view.backgroundColor = UIColor.green 
    } 
    // Calling nested function 
    setBackgroundColor() 
} 

這提高了可讀性,因爲函數定義就在它的使用點。它還提高了可維護性,因爲重構代碼的人可以確定viewDidLoad之外不可以有其他用途setBackgroundColor

當然,這只是一個例子。嵌套函數是沒有必要在這裏 - 你可以重寫它沒有setBackgroundColor功能,如:

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.view.backgroundColor = UIColor.green 
} 
2

我的猜測是,任何效率損失都值得獲得更多可讀代碼。實際上,如果將其標記爲private,則編譯器優化甚至可能內聯該函數。我對Swift編譯器(LLVM)知之甚少,不知道它是否屬實。

Martin Fowler有一個great article on function length其中他說,他有很多函數只是一行,只是因爲它們使代碼更容易理解。

有些人擔心短功能,因爲他們擔心函數調用的性能成本。當我還年輕的時候,這有時候是一個因素,但現在非常罕見。優化編譯器通常可以使用更短的函數更好地工作,這些函數可以更容易地緩存。一如既往,關於性能優化的一般準則是重中之重。

不知道他對功能緩存說明適用於斯威夫特,但他也說:

如果你不得不花費精力投入到尋找的代碼片段,以找出它做什麼 ,那麼你應該把它提取到一個函數中,然後在那個「what」之後命名該函數。這樣,當你再次閱讀時,功能的目的就在你身上跳躍

一般來說,除非你注意到這是一個問題,否則我不會過多地關注優化。 YAGNI

...而作爲代碼不同的是,ViewDidLoad()是隻調用一次。

相關問題