Objective c ObjC类标识符&;编译器魔法?

Objective c ObjC类标识符&;编译器魔法?,objective-c,Objective C,考虑: @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 {

考虑:

@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
在某种程度上

@class self ;
没有道理

在lexer-to-runtime-generator管道中,我可以理解比特流何时从一堆字符变为
标识符
变为依赖于语言的语义元素。但我很难弄清楚ObjC类标识符的确切性质

有人吗

(这似乎不相关)

您可以在以下内容中看到答案:

向类对象发送
class
不会返回其元类,只返回类对象本身

如果出于某种原因需要元类对象,则必须使用运行时函数,如下所示:

NSLog(@"%d", class_isMetaClass(object_getClass([NSString class])));
// Prints 1
您还可以使用获取类名的元类

类方法中的
self
是当前类的
class
对象,因此在这里
self
是class
Foo


下面是class
Foo


这和

Class fooClass = [Foo class];
id fooInstance = [fooClass new];
return [fooInstance class];
同样,给你class
Foo


与前一个相同,只需将
[Foo class]
替换为
self


与前一个相同,只需将
[Foo new]
替换为
[[Foo alloc]init]


与前一个相同,只需将
self
替换为
Foo


与第二个相同,只需将
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运行时函数


我猜在ObjC中,类不是真正的对象(因此没有自己的元类),所以在
类上调用
完全有可能只是故意返回同一个对象。类是对象,@millimoose,但你句子的后半部分就是答案。@JoshCaswell是的。我被
作为结构而不是文档化的问题弄糊涂了。我接受这个答案,因为它提供了有用的链接,但是关于“Foo”作为类标识符的性质的问题仍然没有回答。对不起,我想我错过了这一部分,但我不太确定你想知道什么
Foo
只是一个类型名。只有当类对象是消息的接收者时,才可以使用文本类名称来引用该类对象。事实上,这可能是
+class
返回
self
的原因之一:如果需要类对象作为某个对象的参数,但手头没有实例,可以说
[gardener plantLotsOf:[Oregano class]]
NSLog(@"%d", class_isMetaClass(object_getClass([NSString class])));
// Prints 1
+ (Class) classOf1 {
    return self ;
}
+ (Class) classOf2 {
    return [Foo class] ;
}
+ (Class) classOf3 {
    return [[[Foo class] new] class] ;
}
Class fooClass = [Foo class];
id fooInstance = [fooClass new];
return [fooInstance 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] ;
}
@interface Bar : Foo
@end

Class barClass = [Bar classOf1]; // same as [Bar class]
Class fooClass = [Bar classOf2]; // same as [Foo class]
id metaClass = objc_getMetaClass("Foo");