2

現在我已經有這個問題混淆了我的思想相當長的一段時間,我真的需要有人爲我澄清這一點。指定初始化程序,請澄清。

1)編譯器在被子類型的init方法調用時如何確定指定的初始化方法?因爲它被認爲是覆蓋面最廣的一個。

2)當使用多個init方法進行子類化時,每個類是否都有自己指定的初始化方法?對問題2的回答會增加對理解這一點的幫助。

3)當多個類有一個指定的初始化程序時,其他init方法如何在其類中調用指定的初始化程序?以及他們怎麼也不會調用任何其他初始化器?爲什麼指定的初始化器?它有什麼特別之處?

回答

2

在Objective-C中,類的指定初始化程序是負責正確初始化類並將其置於適當狀態以供使用的方法。代碼中沒有任何東西將它標記爲指定的初始化程序,所以通常在頭文件中有一個註釋。開發人員使用或擴展該類來確定哪種方法是指定的初始化程序(通常爲init或前綴爲init)並相應地編寫代碼。如果它沒有正確記錄並且它的源代碼不可用並且是Swift嘗試解決的缺點之一,這可能會導致錯誤使用類。因此,以解決您的問題...

  1. 指定的初始化不是由編譯器確定。子類還應該有一個指定的初始化程序,它在某個時刻調用super的指定初始化程序。
  2. 每個班級都應清楚地說明(通過評論或文件)哪個初始化設備將被用作指定的初始化設備。開發人員使用該類來確保指定的初始化程序被調用。這是由類的開發人員自己來確保超級的指定初始化器是按照預期調用的。但是,通過正確編寫的類,任何初始方法應該都會調用指定的初始化程序。但是,編譯器無法保證。
  3. 其它初始化方法需要適當地編碼通過[self init...][super init...]來調用指定的初始化。再次,您需要弄清楚如何使用一個類並使用它或適當地擴展它。

指定的初始化程序是執行「繁重」操作以準備要使用的類的新實例的方法。其他初始化器被稱爲便利初始化器,通常用於提供帶有默認默認值的較短簽名,因爲您無法爲Objective-C方法簽名指定默認參數值。

在大多數情況下,如果一個類編寫正確,你真的不應該擔心太多,因爲所有的便利初始化應該結束了調用指定的一個。

在Swift的開發過程中,我們考慮了很多想法,即使您不打算學習它,您也應該閱讀Swift Initializers,因爲它可以讓您深入瞭解適合您的初始化鏈然後可以用它來指導您在Objective-C中創建初始化程序。

更新: 由於Xcode 6,指定的初始值設定項可以這樣標記,通常通過NS_DESIGNATED_INITIALIZER宏。這有助於執行正確書寫的類,並且從Swift中返回到Objective-C。檢出iOS Designated Initializers : Using NS_DESIGNATED_INITIALIZER

+0

如果不是調用DI,而是直接使用便捷初始值設定項直接調用子類中的[super init]或[super init ...],而不是首先調用DI?這也是你的意思,「因爲你不能指定Objective-C方法簽名的默認參數值。」 P.s奇妙地解釋。 –

+0

便利初始值設定項的每個實現都應該調用它自己的DI,如果它有一個,或者它的超級否則。所以是的,你應該這樣做。我從來不需要調用多個初始化器來使用一個類。至於默認參數,如果沒有給出默認參數,則不能指定默認值。其他語言允許類似'func foo(字符串名稱,字符串類別=「無」)',這樣如果您不指定值,則會分配默認值。 –

2
  1. 編譯器沒有以任何方式檢測到它。爲了讓編譯器知道是否指定了初始值設定項,您必須使用NS_DESIGNATED_INITIALIZER宏對其進行註釋。

  2. 如果一個類有初始值設定項,它總是有一個指定的初始值設定項。它實際上可以有多個指定的初始化器。沒有指定的初始化器,你就不能擁有一個類。指定和便利之間的區別非常簡單。指定的初始化器調用[super init...](調用超類初始化器),而方便調用[self init...](調用同一類的另一個初始化器)。

  3. 便捷初始化程序使用[self init...]調用指定的。指定的初始化器並不特殊。它們實際上是最基本的初始化程序。他們做了兩件事 - 他們初始化父(使用[super init...]),然後初始化所需的東西(例如屬性的默認值等)。便捷初始值設定項是一種特殊類型 - 它們是指定初始值設定項的擴展。他們調用指定的初始化器並做更多的事情。例如-initWithStyle:將是一個指定的初始化程序,它將初始化一個對象到特定的樣式。 -initWithStyle:andFrame:將執行相同的操作,但它也會將frame屬性設置爲特定值。如果-initWithStyle:andFrame:使用[self initWithStyle:... andFrame:...]實現,那麼它是一個方便的初始值設定項。

+0

因爲-initWithStyle:andFrame:擁有最參數,是不是會成爲指定的初始化,而不是一個方便的,不是嗎? – cheznead

+1

@shinninja這隻取決於實施,我們無法真正瞭解......兩種方式都是可能的。 – Sulthan

+0

那麼指定的初始化器不一定是那個參數最多的那個呢?它可以比簡單初始化程序少參數? – cheznead

相關問題