是类结构还是结构指针

Mig*_*elC 3 struct class objective-c

如果我没有弄错,结构意味着对象,结构指针意味着指向对象的指针吗?在一篇文章中,它说类是结构,这意味着它们是对象.

Filter the list of all classes
The traditional definition of a class in Objective-C looks like this:

struct objc_class {
    Class isa;
    Class super_class;
    const char *name;
    long version;
    long info;
    long instance_size;
    struct objc_ivar_list *ivars;
    struct objc_method_list **methodLists;
    struct objc_cache *cache;
    struct objc_protocol_list *protocols;
    };
Run Code Online (Sandbox Code Playgroud)

所以,如果它说类是结构体,那么它们如何适应参数objc_msgSend(id self, SEL_cmd)需要一个类型为的结构指针id

Gab*_*lla 8

类是结构体,但是Class是指针类型,被定义为

typedef struct objc_class *Class;
Run Code Online (Sandbox Code Playgroud)

这回答了问题的第一部分.

现在,如果你看看<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;
Run Code Online (Sandbox Code Playgroud)

<obj/runtime.h>你会找到

/// Represents an instance of a class.
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};
Run Code Online (Sandbox Code Playgroud)

意味着在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;
}
Run Code Online (Sandbox Code Playgroud)

这是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;
}
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,类型都设置为结果getObjCObjectPointerType.这会导致编译器同时考虑Objective-C对象Classid指向Objective-C对象的指针.


小智 5

如果我没有弄错,结构意味着对象,结构指针意味着指向对象的指针吗?

大多数情况下,是的.但是,由于在Objective-C,对象(包括类)只能使用指针操纵,简写"对象"来代替更正确的"指针的对象",即使是在正式文件的块.

所以,如果它说类是结构,那么它们将如何适应这个论点objc_msgSend()呢?

它们将指针传递给作为对象的结构.Class是一个typedef struct objc_class *,而是id一个typedef struct objc_object *.两者都是(非函数)指针,并且两个结构都包含一个isa字段,只要您知道自己在做什么,它们就可以互换使用.