[英]Why do we have to put an asterisk on method parameter types in Objective-C?
[英]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
視為類型定義。 *
表示變量m
是pointer to a hunk o' memory that contains one (or many -- don't forget your C pointer-fu) MyClass instances
的pointer 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.