2013-01-09 78 views
0

我目前正在閱讀Apple的「Programming with Objective C」手冊,它顯示了這兩個init方法。他們之間的區別是什麼?每個人什麼時候適合使用?Init方法:這兩者有什麼區別?

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName dateOfBirth: (NSDate *)aDateOfBirth { 

    self = [super init]; 

    if (self) { 
     _firstName = aFirstName; 
     _lastName = aLastName; 
     _dateOfBirth = aDateOfBirth; 
    } 

    return self; 

} 

VS

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName { 
    return [self initWithFirstName:aFirstName lastName:aLastName dateOfBirth:nil]; 
} 

手冊可以在這裏http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW15

+0

第一個是正確的,嘗試一下。如果你嘗試第二種,會發生什麼? –

+1

第二個自己調用,所以會無限循環。這是你打算問的問題還是你可能輸錯了其中一種方法? – isaac

+2

在引用的手冊中,被調用的方法有第三個'dateOfBirth'參數。 – ThomasW

回答

3

發現第二個是圓形的,並且會導致無限遞歸。

編輯:

與更新的問題,初始化的第二個版本只是一個方便,因爲你不再需要指定第三個參數。

+0

也許你可以向OP解釋這種行爲的原因。 –

+0

有趣..爲什麼蘋果會建議在自己的手冊中做這件事? – user1779598

+1

@ user1779598蘋果公司不會......你一定錯誤地鍵入了其中一種方法。如果一個類有多個初始化方法,他們通常會調用一個「指定」初始化程序,這可能是您所指的手冊提示...但您可能沒有完全複製它:) – isaac

0

第一個是正常的自定義初始化,它正確設置您的參數並初始化您的類。

第二個調用自己,所以它會一次又一次地以無限遞歸的方式調用自己,最終導致一個stackoverflow - 應用程序將基本凍結並崩潰。

蘋果文檔並不意味着....你可能看錯了


蘋果文檔仍然不建議,但它接近:

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName { 
return [self initWithFirstName:aFirstName lastName:aLastName dateOfBirth:nil]; // Not the same method, passes dateOfBirth parameter. 
} 

什麼方法被調用可以樣子:

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName dateOfBirth: (NSDate *)dateOfBirth { 

    if (self = [super init]) { 

     _firstName = aFirstName; 
     _lastName = aLastName 
     _dateOfBirth = dateOfBirth; 
    } 

     return self; 

} 

它調用另一種類似的方法,但通過了dateOfBirth參數,其方法不一樣。


好了,所不同的是簡單的,如果調用任何方法不希望類從類中傳遞dateOfBirth參數,而這個人實例沒有一個dateOfBirth他希望指定的編寫代碼的人可能覺得有點不好意思寫nil。所以這是一種方便的方法,你不通過dateOfBirth,只是名字和姓氏,它調用nildateOfBirth的另一種方法。它只是編寫代碼的一種方式,當他編寫nil時不會感到害怕。

因此,一切都在兩種方法中初始化。

+0

也許..但請親切地參考上面的鏈接,看看你自己。我沒有這樣做......它的所有部分「直接從初始化方法訪問實例變量」 – user1779598

+0

已更新的答案。 – MCKapur

+0

夠公平的..所以現在兩種方法有什麼區別? – user1779598

0

正如@ThomasW指出的第二種情況是錯誤的。在第一種情況下,您致電[super init]基地您的類是從您正在實例化的對象的初始化他們的份額派生。

這是有效的,因爲super表明init消息應該由知道該怎麼做的基類接收。請注意,它不知道如何記住你的名字或姓氏。

但是,在第二種情況下,init消息發送到self,這就是您撥打的init。這意味着init將繼續調用,直到你崩潰。

看起來你承擔aFirstNameaLastName是分配一些神奇的方式,但你要教你的對象是如何做到這一點,在這個init方法正是實現它自己。

0

這是寫在手冊中:

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName { 
    return [self initWithFirstName:aFirstName lastName:aLastName dateOfBirth:nil]; 
} 

所以它不會導致無限循環,因爲所調用的方法是另一種,它不是遞歸。

編輯

第二種方法是使用當你不希望初始化與出生日期的對象。事實上,如果您使用initWithFirstName:lastName:,則此屬性將爲零。

+0

建議無限遞歸的評論/答案基於最初發布的錯誤輸入問題。手冊中顯示的內容以及編輯問題中* now *顯示的內容是正確的,並且不會循環。 – isaac