First, what is the object?

Our Xcode is actually very powerful and integrates many cool tools, clang is one of them, we can use the following command to compile the.m file and we can see how our OC compiler to the underlying C or C++

My example here is using the main.m file, Clang-x Objective-c-rewrite-objC-isysroot can be compiled according to the file path of the specific SDK and the file to compile /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk main.m Clang-x objective-c-rewrite-objc-isysroot / Applications/Xcode. App/Contents/Developer/Platforms/iPhoneOS platform/Developer/SDKs/iPhoneOS SDK. The main m / / real machine using a commandCopy the code

When we compile, we see a C++ structure, that’s right, an objec_class structure that looks like this:

  • Why didn’t ISA? –> In the parent structure, direct inheritance
  • Is it an inherited objc_object? –>

  • Why does my object only have one pointer to ISA? –> In fact, I can only explain it in this way, maybe not very professional but the meaning can be clearly expressed. At compile time, all the classes have their own memory space, so you have a unified rough rough, but you have an idea of how to decorate each object. So it’s really quick to instantiate an object just by decorating it the way you want it to be, and labeling it with your own name to indicate ownership.

The mysterious ISA

I mentioned above that the object returns an ISA when instantiated, and the only thing it does is bind our instantiated object to the class. So what is isa? Take a look at this breakdown:

union isa_t {
    isa_t() { } isa_t(uintptr_t value) : bits(value) { } Class cls; // Uintptr_t bits; / / a domain#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
#endif
};
Copy the code
  • We see that it is a union, which can be bits or CLS. This further illustrates the nature of objects.
  • So how else can bits bind classes? Let’s see what bits has
# define ISA_BITFIELD \uintptr_t nonpointer : 1; Uintptr_t has_assoc: 1; Uintptr_t has_cxx_dtor: 1; Uintptr_t shiftcls: 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ Uintptr_t Weakly_referenced: 1; uintptr_t weakly_referenced: 1; Uintptr_t deallocating: 1; Uintptr_t has_sidetable_rc: 1; Uintptr_t extra_rc: 19 uintptr_t extra_rc: 19 uintptr_t extra_rc: 19Copy the code

This is a macro – defined bitfield, followed by a number indicating the number of digits held. Isa has been optimized to make efficient use of an 8-byte space to store more things, such as the CLS stored in ShiftCLs.

Isa walk a

I’m sure many of you already know this, but when it comes to ISA, I’d like to introduce you

  • Instantiate the object’s ISA -> class, the class’s ISA -> metaclass, the metaclass’s ISA -> root metaclass, the root metaclass’s ISA -> root metaclass itself. That’s kind of the flow, if it’s an NSObject instantiation object it’s one less.
  • Isa bitmap is attached
  • Isa bitmap interpretation, dotted line indicates isa bitmap interpretation, solid line indicates superclass inheritance relationship. RootClass is NSObject, everything is an object

What is cache?

In fact, it would be a waste of time for the Runtime to do a message lookup and throw it away after each lookup. Frequently used or recently searched methods are cached, which increases the efficiency of method calls. Specific introduction can reference I have written before about cache_t analysis of https://juejin.cn/post/6844904040153743368

4. What are bits?

If we’re curious, where are all the properties and methods I wrote since there’s nothing left after the object is instantiated? Is it in the class? That’s true, but the class is relative, the class is the class of objects, the metaclass is the class of classes, and so on. Bits contains the attributes and instantiation methods of the object.

1. Bits

We can see that bits.data() returns a pointer to the class_rw_t * structure, indicating that the bits contain the structure data.

  • What does RW mean, readable and writable region? Who wrote it? Certainly not we ordinary iOS developers to write in, is the compiler in the compile, run phase of the code class, object parsing translation, write methods, attributes, protocols into such a readable and writable area.
  • Is it all here? It isn’t. Class_ro_t, read only and a read-only area
  • What does it say in the RW? Classes, methods in class extensions, attributes, protocols.
    uint32_t flags;
    uint32_t version;

    const class_ro_t *ro;

    method_array_t methods;
    property_array_t properties;
    protocol_array_t protocols;

    Class firstSubclass;
    Class nextSiblingClass;

    char *demangledName;
Copy the code
  • Class_ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t () {class ro_t ()}} This member variable is stored in ivars.
struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
#ifdef __LP64__
    uint32_t reserved;
#endif

    const uint8_t * ivarLayout;
    
    const char * name;
    method_list_t * baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;

    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;

    method_list_t *baseMethods() const {
        returnbaseMethodList; }};Copy the code

2, actually look at the verification

Let’s start with a custom class, configure objC’s source code, and use LLDB to debug the data in memory

  • Prepare a custom class to be called directly from the main function

  • Gets the data in bits

  • Data in RO

  • Read the property, the nickName is already the first one in the array, and the total is also one (our class only writes one).

  • Read methods, set and get methods for attributes, an instantiator we defined ourselves, and a c++ function

  • Read member variables, hobby, and the _nickName automatically generated by the property are all there

Five, write in the last impression

In the process of those at the bottom of the study, thinking about thinking on the development of the apple development engineer and design thought is a very enjoy thing, figure out how they make the efficiency of the code is so high is good for their own development level help, written in c + + game friends estimate experience more deeply, the game all are own implementation, Except for the scene and the game engine used for rendering.

Interested in communicating with friends, you can add QQ:578200388