是类结构还是结构指针

时间:2013-10-19 18:05:24

标签: objective-c class struct

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

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;
    };

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

2 个答案:

答案 0 :(得分:8)

类是结构体,但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_objectobjc_class是相同的结构,两者都有isa字段。

这就是为什么你可以传递Class所需的idclasses are objects after all

您通常会期望关于不兼容指针类型的警告,但显然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的结果。这会导致编译器将Classid都视为Objective-C对象的指针。

答案 1 :(得分:5)

  

如果我没弄错,结构是指对象,结构指针是指对象的指针吗?

大多数情况下,是的。但是因为在Objective-C中,对象(包括类)只能使用指针进行操作,所以使用速记“对象”而不是更正确的“指向对象的指针”,即使在官方文档中也是如此。

  

那么,如果它说类是结构,那么它们如何适合objc_msgSend()的参数?

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