繁体   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