类是结构,但是Class
是指针类型,被定义为
typedef struct objc_class *Class;
这回答了问题的第一部分。
现在,如果你看看<objc/objc.h>
你会发现
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
<obj/runtime.h>
你会发现
/// Represents an instance of a class.
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
这意味着在 Objective-C 2.0中objc_object
,objc_class
它们是相同的结构,都具有一个isa
字段。
这就是为什么你可以在需要的Class
地方传递一个id
:类毕竟是对象。
您通常会收到有关不兼容指针类型的警告,但显然 Obj-C 编译器在这种特定情况下使用了特别处理。
不过,我没有参考资料来支持这一点。
编辑
终于在clang源码中找到了参考:
中ASTContext.cpp
,这是Class
声明
TypedefDecl *ASTContext::getObjCClassDecl() const {
if (!ObjCClassDecl) {
QualType T = getObjCObjectType(ObjCBuiltinClassTy, 0, 0);
T = getObjCObjectPointerType(T);
TypeSourceInfo *ClassInfo = getTrivialTypeSourceInfo(T);
ObjCClassDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
getTranslationUnitDecl(),
SourceLocation(), SourceLocation(),
&Idents.get("Class"), ClassInfo);
}
return ObjCClassDecl;
}
这是id
声明
TypedefDecl *ASTContext::getObjCIdDecl() const {
if (!ObjCIdDecl) {
QualType T = getObjCObjectType(ObjCBuiltinIdTy, 0, 0);
T = getObjCObjectPointerType(T);
TypeSourceInfo *IdInfo = getTrivialTypeSourceInfo(T);
ObjCIdDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
getTranslationUnitDecl(),
SourceLocation(), SourceLocation(),
&Idents.get("id"), IdInfo);
}
return ObjCIdDecl;
}
在这两种情况下,类型都设置为getObjCObjectPointerType
. 这会导致编译器同时考虑Class
和id
作为指向 Objective-C 对象的指针。