簡體   English   中英

為什么我們必須在Objective-C中做[MyClass類]?

[英]Why do we have to do [MyClass class] in Objective-C?

在Objective-C中,您可以使用以下命令調用類方法:

[MyClass aClassMethod];

您可以使用以下命令查詢實例的類型:

[someInstance isKindOfClass:[MyClass class]];

但是,為什么我們需要做[MyClass class] ,而不是像這樣提供MyClass

[someInstance isKindOfClass:MyClass];

有沒有理由認為編譯器遇到MyClass作為接收器(指針類型)而不是作為參數? 這是解析語言的限制嗎? 或者也許是編譯器的限制?

噢〜有趣的問題。 答案是c-ism。

考慮:

@interface MyClass : NSObject
@end
@implementation MyClass
@end

現在,說你有:

...
MyClass *m = nil;
...

在該上下文中,編譯器將MyClass視為類型定義。 *表示變量mpointer to a hunk o' memory that contains one (or many -- don't forget your C pointer-fu) MyClass instancespointer to a hunk o' memory that contains one (or many -- don't forget your C pointer-fu) MyClass instances

換句話說, MyClass是一種類型。

但是,在類似的情況下:

[someInstance isKindOfClass: x ];

x必須是rvalue,或者在人類術語中, 是表達式的值 但是,類型不能用作右值。

[MyClass class]工作實際上是一種黑客攻擊,無論是在語言還是編譯器中,語法都特別允許類型名稱作為消息接收者(作為方法調用的目標)。

而且,事實上,你可以這樣做:

typedef MyClass Foo;
....
[MyClass class];
[Foo Class];

一切都會奏效。 但是,您無法執行以下操作, 錯誤消息很明亮:

[NSUInteger class];

錯誤:'NSUInteger'不是Objective-C類名或別名


現在,為什么不是特殊情況它到處都是一個裸名?

這包括類型名稱和rvalues,你很快就會吞下類似[foo isKindOfClass: (MyClass)]; [foo isKindOfClass: (MyClass *)];上進行barfing [foo isKindOfClass: (MyClass *)]; 然后以一種相當不舒服的方式侵占類型轉換領域。

有趣。

在Objective-C中,類名有兩個角色,作為數據類型和類對象。 作為數據類型名稱,您可以執行以下操作:

MyClass *anObject;

作為類對象,類名只能表示類對象作為消息接收者。 這就是你必須使用的原因

... isKindOfClass:[MyClass class] ...

但是,我不認為這是滿足您需求的答案。 對我來說,答案是,“是的,你想要的是合情合理的。但規范說的是另一種方式”。

Page 32, section: "Class Names in Source Code" . 參考: 第32頁,節:“源代碼中的類名”

@John和@ryanprayogo - 你們都是根本錯的。 MyClass是一個Class,它也是一個對象,但不從NSObject繼承。 Objective-C有點奇怪,但在完全解釋時它實際上很棒(見這里 )。 不過,這里的答案是@yehnan所說,類名可以是聲明者和強制轉換的類型名稱,也可以是消息的接收者。 [MyClass class]的實現返回self(在方法中,MyClass)。 同樣正如@yehnan所說,這種語言可以支持將其作為論據傳遞,盡管它根本不支持。

我的第一眼回答是因為[MyClass類]返回類型為Class的對象,而MyClass不繼承自Class ...

@yehnan抓住了它,但我會稍微擴展一下。 是的,編譯器可以被修改為在類參數的地方自動將類標識符轉換為適用的Class ,而不是僅在它是消息的目標時。 但是在編譯器中沒有太多要求增加復雜性(翻譯:更慢,更難以檢測編碼錯誤)。 你不應該經常調用返回Class東西。 如果是,那么您的對象模型就會被破壞。 在其他一切都失敗之后,類檢查應該是最后一種絕望的方法(最明顯的是正確的輸入,然后是respondsToSelector: 因此,對於這種罕見的事件,以這種方式使編譯器復雜化並沒有多大意義。

因為isKindOfClass期望的是一個“類”,這是從調用返回的內容: [MyClass class]

我認為MyClass實際上是一個元類。 您發送類消息以獲取實際類(類型為Class)。

MyClass不是Class類型。

[MyClass class]Class類型。

如果您熟悉Java,則概念是相同的。

java.lang.String的類型不是java.lang.Class

java.lang.String.getClass()的類型為java.lang.Class

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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