考虑:
@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个案例都返回完全相同的值!
对我来说最令人费解的案例是:
在后者`self'中表示“Foo是一个类。那么什么是班级?
显然,“Foo”和“self”在这种情况下扮演着完全相同的角色。就像他们在
中一样在我看来,“Foo”是一个神奇的兔子。
你可以
@class Foo ;
以某种方式
@class self ;
没有意义。
在词法分析器到运行时生成器管道中,我可以理解比特流何时从一串字符变为identifier
到语言相关的语义元素。但我很难弄清楚ObjC类标识符的确切性质。
任何?
(这SO Question似乎无关)
答案 0 :(得分:8)
您可以在NSObject's implementation中找到答案:
+ (Class)class {
return self;
}
- (Class)class {
return object_getClass(self);
}
向类对象发送class
不返回其元类,只返回类对象本身。
如果由于某种原因需要元类对象,则必须使用运行时函数object_getClass()
,如下所示:
NSLog(@"%d", class_isMetaClass(object_getClass([NSString class])));
// Prints 1
您还可以使用objc_getMetaClass()
获取类名称的元类。
答案 1 :(得分:5)
+ (Class) classOf1 {
return self ;
}
类方法中的 self
是当前类的Class
对象,所以在这里self
是类Foo
的类对象
+ (Class) classOf2 {
return [Foo class] ;
}
这是类Foo
+ (Class) classOf3 {
return [[[Foo class] new] class] ;
}
这与
相同Class fooClass = [Foo class];
id fooInstance = [fooClass new];
return [fooInstance class];
再次,为您提供类Foo
+ (Class) classOf4 {
return [[self new] class] ;
}
与上一张相同,只需将[Foo class]
替换为self
+ (Class) classOf5 {
return [[[self alloc] init] class] ;
}
与上一张相同,只需将[Foo new]
替换为[[Foo alloc] init]
+ (Class) classOf6 {
return [[[Foo alloc] init] class] ;
}
与上一张相同,只需将self
替换为Foo
+ (Class) classOf7 {
return [self class] ;
}
与第二个相同,只需将Foo
替换为self
在类方法中使用Foo
和self
之间的区别在于,当在子类上调用此方法时,self
将替换为子类。 e.g。
@interface Bar : Foo
@end
Class barClass = [Bar classOf1]; // same as [Bar class]
Class fooClass = [Bar classOf2]; // same as [Foo class]
如果你真的想要获得类的类(即元类),你需要使用<objc/runtime.h>
中的objc运行时函数
id metaClass = objc_getMetaClass("Foo");