簡體   English   中英

Objective-C理解isKindOfClass

[英]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_topItemOnStackid類型而我沒有將它轉換為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

您可以將任何消息發送到idnil的類型為id ),而無需將其強制轉換為特定的類。 不過,你應該謹慎,因為一個無法識別的選擇器會導致崩潰。

編輯:
id表示:指向未知類的Objective-C對象的指針

如果你想更多地了解idvoid *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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM