2016-07-31 54 views
7

我的同事有時會在覆蓋ios方法時調用super而有時不會。這似乎主要基於他們的經驗。在決定是否調用super時有沒有經驗法則?何時使用超級重寫ios方法

例:

// Has super 
override func awakeFromNib() { 
    super.awakeFromNib() 
} 

// No super 
override func drawRect(rect: CGRect) { 
} 
+2

經驗法則是「閱讀文檔」。 – matt

+1

@matt您的評論無人幫助,請提供對文檔或其他SO帖子的參考。 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-ID196 – alexisSchreier

+0

@alexisSchreier我不同意。我已經非常直接,簡潔和正確地回答了這個問題。要知道在執行'awakeFromNib'時是否要調用super,你必須閱讀'awakeFromNib'上的文檔。等等。沒有更短的路徑。我的評論可以幫助大家。 – matt

回答

5

對於是否應該調用給定方法的超級實現,沒有真正的經驗法則。這是應根據個案情況確定的事情,具體取決於超文檔實施該方法的文檔建議以及您的要求。

只是爲了解釋爲什麼你包括了兩個例子可能是他們,我們可以看一下文檔-[UIView drawRect:],其中規定的方式:

如果你繼承UIView的直接,你的這種方法 的實施不需要調用超級。但是,如果您要繼承不同的視圖類,則應該在您的 實施中的某個時刻調用super。

-[NSObject awakeFromNib]的文件,其中規定:

你必須調用超級實現awakeFromNib的給父母 類執行任何額外的初始化他們 需要的機會。儘管此方法的默認實現沒有任何功能,但許多UIKit類都提供了非空實現。

大多數情況下,您應該調用方法的超級實現(請參閱下面的註釋),這可能是一個安全的選擇。但是,需要注意的是,有些方法需要你調用他們的超級實現,有些則不需要,有些甚至要求你在超馳實現的特定位置調用超級實現。所以請記住,如有疑問,請務必查閱文檔。

+3

我會以不同的方式回答這個問題。對於剛開始的開發者,我會說「總是稱之爲超級實現」。如果編譯器抱怨方法未定義,請刪除該調用。有時你不需要調用super,因爲基類的超級實現沒有任何作用,但是當你不需要時調用它比在不需要時調用它更安全,而不是在需要時調用它。 –

+1

@DuncanC這是一個很好的觀點。如果有疑問,調用super可能是一個更安全的默認位置,可以在一般情況下使用。儘管(並且我沒有想到一個例子),但是可能會出現這樣的情況:方法的超級實現具有副作用,這些副作用會改變子類的實現中的代碼也已更改的狀態。在這種情況下,將超級呼叫放置在您的覆蓋範圍內會很重要,並可能導致更多混淆。 –

+2

我相信規範是先調用超級版本,然後添加您的自定義代碼。這樣,在超級實現完成之後,您對該方法所做的任何更改都會應用。 –

0

發送消息到超級是一種方法,通過調用由一個超類進一步向上繼承鏈中定義的方法實現。 super的最常用用法是覆蓋方法。調用super將允許父類做一些準備。如果你重寫一個方法,你必須調用super,否則你可能會有一些無效的狀態,因爲超級類實現已經錯過了初始化某些狀態。

+1

「如果你重寫一個方法,你必須調用超級方法」。實際情況並非如此 - 它取決於具體的方法,如果必須的話。 – Gruntcakes

+0

是的,例如['UIViewController loadView'](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/instm/UIViewController/loadView)明確地說:「你的這個方法的自定義實現不應該調用super。」我的建議是總是檢查文檔,如果文檔沒有說明,如果有疑問,請默認調用超級。關於Android和iOS的一個好處是你有源代碼,可以去看看超級實際上做了什麼。 : -/ –

+0

@i_am_jorf我沒有在文檔鏈接的任何地方看到這一點。 –

相關問題