Are classes structs or struct pointer

前端 未结 2 1048
野性不改
野性不改 2021-01-03 08:50

If I\'m not mistaken, structs mean objects, and struct pointers mean pointer to objects right? In an article, It says that classes are structs which means that they are obje

相关标签:
2条回答
  • 2021-01-03 09:18

    Classes are structs, but Class is a pointer type, being defined as

    typedef struct objc_class *Class;
    

    and this answers the first part of the question.

    Now, if you take a look at <objc/objc.h> you'll find

    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;
    

    and in <obj/runtime.h> you'll find

    /// Represents an instance of a class.
    struct objc_object {
        Class isa  OBJC_ISA_AVAILABILITY;
    };
    

    meaning that in Objective-C 2.0 objc_object and objc_class are identical structs, both having an isa field.

    That's why you can pass a Class where an id is required: classes are objects after all.

    You would normally expect a warning about the incompatible pointers type, but apparently the Obj-C compiler uses an ad-hoc treatment this specific case. I have no references to support this, though.

    EDIT

    I finally found a reference in the clang source code:

    In ASTContext.cpp, this is the Class declaration

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

    and this is the id declaration

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

    In both cases the type is set to the result of getObjCObjectPointerType. This causes the compiler to consider both Class and id as pointers to Objective-C objects.

    0 讨论(0)
  • 2021-01-03 09:37

    If I'm not mistaken, structs mean objects, and struct pointers mean pointer to objects right?

    Mostly, yes. But since in Objective-C, objects (including classes) can only be manipulated using pointers, the shorthand "object" is used instead of a more correct "pointer to an object", even in pieces of official documentation.

    So, if it says that classes are structs, then how will they fit in the argument of objc_msgSend()?

    They pass a pointer to a struct which is an object. Class is a typedef for struct objc_class *, whereas id is a typedef for struct objc_object *. Both are (non-function) pointers, and both structures contain an isa field, they can be used interchangeably as far as you know what you are doing.

    0 讨论(0)
提交回复
热议问题