2011-06-18 29 views
1

考慮下面的代碼:基本的Objective-C類型轉換問題

if([obj isKindOfClass:[NSString class]]) { 
    NSString *s = [(NSString *)obj stringByAppendingString:@"xyzzy"]; 
} 

我有點困惑在這裏。 if語句檢查是否爲NSString類。如果是,它將該對象和一個附加字符串分配給NSString *s,我是否正確理解這一點?如果是這樣,你爲什麼仍然投它(NSString *)if語句是否已經檢查過,並且不會導致類型轉換不必要?

豈不是完全正常的,只是說:提前

NSString *s = obj stringByAppendingString:@"xyzzy"];

感謝。

+1

請注意,基於'isKindOfClass:'的編碼非常不典型。如果你不知道給定的對象引用實際是什麼類型,它通常表示僞造的體系結構。 – bbum

+0

我明白了。這是CS193P幻燈片的一個例子;我會記住你的評論!謝謝。 – cabaret

+0

@bbum我不會這麼說。 「isKindOfClass:'有很多合法用例,這是合理的。例如。某些方法需要允許調用者提供一個未知類的參數,在這種情況下,您可以在方法定義中使用'id'「類」,並依靠'isKindOfClass:'來相應地處理不同的類型。 –

回答

3

這一切都取決於如何定義obj。如果是id obj則不需要轉換,但如果定義爲NSObject *obj,則轉換是必要的,以抑制編譯器警告stringByAppendingString:未在NSObject上定義。在運行時不需要強制轉換代碼,它只會告訴編譯器「正確」的類型,因此它可以判斷方法是否應該存在於對象上。

爲什麼不需要用於id鑄造的原因是因爲id意味着「任何類型的對象」,而NSObject *意味着「類型NSObject的的目的」。

+0

我想我懂'id'。但是,如何將定義爲'NSObject * obj'的對象通過if子句?它正在測試'NSString類',對吧?或者它會通過,因爲'NSString'繼承自'NSObject'? – cabaret

+0

'obj'可能包含'NSString *',因爲'NSString'是從'NSObject'派生的。但編譯器在'if'時只知道'NSObject'方法('isKindOfClass:'是'NSObject'中定義的方法之一),但它還不知道已定義的其他方法在'NSString'類中。 'if'現在檢查'obj'中的對象是否不僅僅是一個'NSObject',而是檢查它是否實際上是'NSString'。如果檢查通過,我們知道它是一個'NSString',現在你需要告訴編譯器像處理那樣對待它。 – DarkDust