[英]Objective-C understanding isKindOfClass
最新版本的Objective-C和XCode(4.4)。
我有一個代碼片段,我無法理解為什么我能夠使用某些行,讓我解釋一下:
// For understanding purpose : (NSMutableArray*)_programStack
id l_topItemOnStack = [_programStack lastObject];
if([l_topItemOnStack isKindOfClass:[NSNumber class]])
{
return [l_topItemOnStack doubleValue];
}
我的問題:因為我的l_topItemOnStack
是id
類型而我沒有將它轉換為NSNumber
,我怎么能使用[l_topItemOnStack doubleValue]
。
我猜我必須首先將其轉換為NSNumber以訪問NSNumber方法...
我在這里錯過了什么?
因為Objective-C是一種動態語言,所以消息名稱及其聲明只是編譯器的提示 - 實際的消息查找和發送在運行時發生。 因此,即使編譯器不知道您的對象響應doubleValue
消息,它仍然可以調用
return objc_msgSend(l_topItemOnStack, @selector(doubleValue));
和往常一樣。
此外,編譯器查找在包含的頭中任何地方聲明的所有選擇器,並嘗試使用實際上下文找到最佳匹配 - 這里doubleValue是一個唯一名稱 - 它僅在NSNumber上聲明,因此編譯器假定您的對象確實是一個NSNumber。
如果你真的想避免這種情況,可以在調用方法時強制轉換對象,或者最初將其聲明為NSNumber。
id
表示任何Objective-C類。 它與NSObject *
,因為在這種情況下,您將無法使用-doubleValue
方法而不首先將其強制轉換為NSNumber
。
您可以將任何消息發送到id
( nil
的類型為id
),而無需將其強制轉換為特定的類。 不過,你應該謹慎,因為一個無法識別的選擇器會導致崩潰。
編輯:
id
表示:指向未知類的Objective-C對象的指針
如果你想更多地了解id
, void *
和NSObject *
之間的區別,你應該閱讀這篇博文: http : //unixjunkie.blogspot.de/2008/03/id-vs-nsobject-vs-id.html
編譯器只是將對象與轉換可見的選擇器匹配(通過#import
)。
如果在查找選擇器匹配時存在歧義,或者如果簽名不匹配並且聲明了多個選擇器,則可能會抱怨。 在這種情況下,您要么必須轉換對象:
return [(NSNumber*)l_topItemOnStack doubleValue];
或將其分配給一個新變量:
NSNumber * number = l_topItemOnStack;
return [number doubleValue];
為了消除編譯器的類型歧義,以便知道正確的選擇器的簽名(例如,它可以正確設置堆棧)。
在MRC中,編譯器實際上可以“假設”參數並返回類型(默認為id
) - 但在ARC中禁止使用。
首先,檢查topItemOnStack是否為NSNumber的 類型,因為NSNumber繼承了NSValue
NSValue對象是單個C或Objective-C數據項的簡單容器。 它可以包含任何標量類型,如int,float和char,以及指針,結構和對象id
topItemOnStack can now be of any type floatValue, intValue or doubleValue as per our requirement
通過使用isKindOfClass不會將topItemOnStack轉換為NSNumber,而是檢查它是否為NSNumber類型。
isKindOfClass指示接收者是給定類的實例還是從該類繼承的任何類的實例
Objective-C對象具有捆綁在(着名的isa
指針)中的運行時類型信息。
您可以向任何對象發送任何消息; 如果編譯器無法找到編譯時類型信息來判斷對象是否響應選擇器(在本例中為doubleValue
),編譯器會抱怨(警告),但我相信id
類型的對象是通用的,不受此規則的約束,任何事情都發生在編譯時( 有人更有見識,請確認一下 )。
當然,如果id類型的變量指向的對象沒有實現相應的方法(即,無法響應發送的消息),則會拋出異常。 在iOS中,這意味着應用程序崩潰(除非有問題的對象已覆蓋此默認行為)。 在OS X上,並不總是( 再次,有人更有見識,請確認一下 )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.