2012-07-12 36 views
4

我讀到使用init方法中的屬性被認爲是不好的做法。但是,我應該使用父類專有?Objective-c在初始化方法中使用父屬性

例如

-(id) init 
{ 
    if (self = [super init]) 
    { 
     self.parentProp = someVal; // (1) 
     parentProp = someVal; // (2) 
    } 

    return self; 
} 

什麼是首選(1或2),爲什麼呢?謝謝!

回答

3

在調用super的init方法並返回後,超類的對象部分將被初始化並可供使用。這是正常的,並期望您在此之後使用它的屬性訪問器。例如。如果您創建了UIViewController的子類,那麼在您的init方法中設置(繼承)title屬性或修改navigationItem是正常的。

也就是說,你可以打破這種行爲。如果你已經重寫了一個超類的方法(包括它的一個訪問方法),然後你在你的init方法中調用了這個方法,那麼在你的對象被完全初始化之前,要確保你的重寫方法能夠正常工作。

更微妙的是,也許你重寫了一個超類的方法,然後你調用不同的超類方法,你沒有覆蓋。那麼,如果您調用的方法轉身並調用重寫了的方法呢?你也需要意識到這種可能性。

所有這一切,我重申,通過調用其init方法之一來初始化它後,使用你的超類的屬性訪問器來定製它是完全正常的。

+0

所以我可以期望在init方法中我的類的完全多態行爲? (我在問,因爲我最熟悉的語言是C++,並且如果從構造函數調用虛函數,則會引發問題) – Andrew 2012-07-13 04:40:39

+0

是的,除非明確發送消息,否則始終會獲得派生方法的派生最多版本到「超級」。這與C++中的對象構造完全不同(並且更簡單)。 – 2012-07-13 06:26:16

1

要回答你的問題 - 他們都沒有。

  1. (2)不是屬性訪問,而是直接實例變量訪問。這取決於類的層次結構設計,但總的來說,我強烈建議不要在非專用接口中使用ivars - 有關詳細信息,請參閱this answer to related question
  2. 一般而言,不應使用類公有方法的任何(包括屬性訪問)在類初始化器(和dealloc中的那個問題) - 如果你的類層次結構不禁止明確的子類化。因爲如果你這樣做 - 覆蓋這些方法(或屬性訪問器)的子類會在無效狀態(尚未初始化或已經釋放)時調用它們。

雖然我遇到了一些由pt.2引起的一般問題,但忽略它似乎是一種常見的做法(即在初始化器中使用self/parent類屬性)。所以我會說這取決於你。要麼在您的類初始化程序之外編寫更多用於顯式設置的代碼,並確信您永遠不會遇到此問題。或者可能有更簡單/更簡單的初始化和更簡單的類的使用,但要留意這個問題。