在Objective-C中,您可以使用以下命令调用类方法:
[MyClass aClassMethod];
Run Code Online (Sandbox Code Playgroud)
您可以使用以下命令查询实例的类型:
[someInstance isKindOfClass:[MyClass class]];
Run Code Online (Sandbox Code Playgroud)
但是,为什么我们需要做[MyClass class],而不是简单地提供MyClass这样的:
[someInstance isKindOfClass:MyClass];
Run Code Online (Sandbox Code Playgroud)
有没有理由认为编译器遇到MyClass接收器(指针类型)而不是作为参数?这是解析语言的限制吗?或者也许是编译器的限制?
bbu*_*bum 41
噢〜有趣的问题.答案是c-ism.
考虑:
@interface MyClass : NSObject
@end
@implementation MyClass
@end
Run Code Online (Sandbox Code Playgroud)
现在,说你有:
...
MyClass *m = nil;
...
Run Code Online (Sandbox Code Playgroud)
在该上下文中,编译器将其MyClass视为类型定义.该*说的变量m是pointer to a hunk o' memory that contains one (or many -- don't forget your C pointer-fu) MyClass instances.
换句话说,MyClass是一种类型.
但是,在类似的情况下:
[someInstance isKindOfClass: x ];
Run Code Online (Sandbox Code Playgroud)
x必须是一个右值,或者在人类方面,它必须是一个表达式的值.但是,类型不能用作右值.
这[MyClass class]在语言和编译器中实际上都是一种黑客攻击,因为语法特别允许类型名称作为消息接收者(作为方法调用的目标).
而且,事实上,你可以这样做:
typedef MyClass Foo;
....
[MyClass class];
[Foo Class];
Run Code Online (Sandbox Code Playgroud)
一切都会奏效.但是,您无法执行以下操作,但错误消息很明亮:
[NSUInteger class];
Run Code Online (Sandbox Code Playgroud)
错误:'NSUInteger'不是Objective-C类名或别名
现在,为什么不是特殊情况它到处都是一个裸名?
这就是类型名称和rvalues的结合,你很快就会不得不吞下像[foo isKindOfClass: (MyClass)];barfing 那样的东西[foo isKindOfClass: (MyClass *)];,然后以相当不舒服的方式侵占类型转换领域.
有趣.
在Objective-C中,类名有两个角色,作为数据类型和类对象.作为数据类型名称,您可以执行以下操作:
MyClass *anObject;
Run Code Online (Sandbox Code Playgroud)
作为类对象,类名只能表示类对象作为消息接收者.这就是你必须使用的原因
... isKindOfClass:[MyClass class] ...
Run Code Online (Sandbox Code Playgroud)
但是,我不认为这是满足您需求的答案.对我来说,答案是,"是的,你想要的是合情合理的.但规范说的是另一种方式".
参考:Objective-C编程语言第32页,节:"源代码中的类名".
| 归档时间: |
|
| 查看次数: |
2288 次 |
| 最近记录: |