考虑:
@interface Foo : NSObject + (void) dump ; @end @implementation Foo + (Class) classOf1 { return self ; } + (Class) classOf2 { return [Foo class] ; } + (Class) classOf3 { return [[[Foo class] new] class] ; } + (Class) classOf4 { return [[self new] class] ; } + (Class) classOf5 { return [[[self alloc] init] class] ; } + (Class) classOf6 { return [[[Foo alloc] init] class] ; } + (Class) classOf7 { return [self class] ; } + (void) dump { NSLog(@"classOf1 %@<0x%08.8lx>",[self classOf1],(unsigned long)[[self classOf1] hash]) ; NSLog(@"classOf2 %@<0x%08.8lx>",[self classOf2],(unsigned long)[[self classOf2] hash]) ; NSLog(@"classOf3 %@<0x%08.8lx>",[self classOf3],(unsigned long)[[self classOf3] hash]) ; NSLog(@"classOf4 %@<0x%08.8lx>",[self classOf4],(unsigned long)[[self classOf4] hash]) ; NSLog(@"classOf5 %@<0x%08.8lx>",[self classOf5],(unsigned long)[[self classOf5] hash]) ; NSLog(@"classOf6 %@<0x%08.8lx>",[self classOf6],(unsigned long)[[self classOf6] hash]) ; NSLog(@"classOf7 %@<0x%08.8lx>",[self classOf7],(unsigned long)[[self classOf7] hash]) ; } @end
并输出:
2013-07-04 03:20:20.404 WC[29862:c07] classOf1 Foo<0x0002a2e4> 2013-07-04 03:20:21.075 WC[29862:c07] classOf2 Foo<0x0002a2e4> 2013-07-04 03:20:21.628 WC[29862:c07] classOf3 Foo<0x0002a2e4> 2013-07-04 03:20:22.229 WC[29862:c07] classOf4 Foo<0x0002a2e4> 2013-07-04 03:20:22.805 WC[29862:c07] classOf5 Foo<0x0002a2e4> 2013-07-04 03:20:23.387 WC[29862:c07] classOf6 Foo<0x0002a2e4> 2013-07-04 03:20:25.235 WC[29862:c07] classOf7 Foo<0x0002a2e4>
所有7个案例都返回完全相同的值!
对我来说最令人费解的案例:
> classOf1和classOf7
在后者中,“自我”代表“Foo,这是一个阶级.那么班级的课程是什么?
> classOf5和classOf6
显然,“Foo”和“self”在这种情况下扮演着完全相同的角色.正如他们所做的那样
> classOf3和classOf4
在我看来,“Foo”是一个神奇的兔子.
您可以
@class Foo ;
在某种程度上
@class self ;
没有意义.
在词法分析器到运行时生成器流水线中,我可以理解比特流何时从一串字符变为标识符到语言相关的语义元素.但我很难弄清楚ObjC类标识符的确切性质.
任何人?
(这SO Question似乎无关)
解决方法
您可以在
NSObject’s implementation中看到答案:
+ (Class)class { return self; } - (Class)class { return object_getClass(self); }
将类发送到类对象不会返回其元类,只返回类对象本身.
如果由于某种原因需要元类对象,则必须使用运行时函数object_getClass()
,如下所示:
NSLog(@"%d",class_isMetaClass(object_getClass([NSString class]))); // Prints 1
您还可以使用objc_getMetaClass()
获取类名的元类.