This is the third day of my participation in the August More Text Challenge

First, the nature of the object

1, clang

  • Clang is a lightweight compiler for C, C++, and Objective-C. Source code is published under the BSD protocol. Clang will support its normal lambda expressions, simplified handling of return types, and better handling of constEXPr keywords.
  • Clang is an Apple-led, LLVM-based C/C++/Objective-C compiler

clangThe command

Clang-x objective-c-rewrite-objc main.m -o main.cpp UIKit error clang-x objective-c-rewrite-objc-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk main.mCopy the code

Xcode is installed with the xcrun command, which is a bit more wrapped around clang to make it easier to use

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * clang -arch arm64 -rewrite-objc main.m -o main- arm64.cppCopy the code

2. Explore the nature of the object

2.1 The essence of an object is a structure

Introduce an example inmain.mAdd to fileLRPersonClass declaration and implementationOpen the terminal,cdTo the current directory, run the following commandmain.mCompiled intomain.cppfile

clang -rewrite-objc main.m -o main.cpp 
Copy the code

main.cppIt’s a lot of code, over 100,000 lines. Global searchLRPerson, a structure is foundLRPerson_IMPLIt just happens to be inside_name. Empirically, objects are found to be structures in nature LRPerson_IMPLIn addition to member variables_nameAnd one moreNSObject_IVARS, it is aNSObject_IMPLLet’s do a searchNSObject_IMPL, you can see the following definition:soNSObject_IVARSisisa

2.2 and expanding

1. There is a line above the LRPerson_IMPL structure that shows that LRPerson is of type objc_object, where objc_Object is the underlying implementation of NSObject.

typedef struct objc_object LRPerson;
Copy the code

Class is a struct pointer of type objC_class. Our common id is the structure pointer of type objc_Object, which explains why the ID type can modify any object; SEL is also a structure pointer.

typedef struct objc_class *Class;
typedef struct objc_object *id;
typedef struct objc_selector *SEL;
Copy the code

3, inLRPerson_IMPLBelow the structure you can see the following code, here isnameProperties of theGet/set methods You can findGet/set methodsBoth have two hidden parametersselfand_cmd, that is,Method receiverandApproach number.Get/set methodsIs read and assigned based on the initial address of the object and the offset value of the member variable.

Two, the commonwealth bit domain

Let’s talk about unions and bitfields

struct LRCar1 { 
    BOOL front; 
    BOOL back; 
    BOOL left; 
    BOOL right; 
};
Copy the code

This is an orientation structure, LRCar1, 1 byte for BOOL, 4 bytes for this structure, 32 bits. For a BOOL with a value of 0 or 1, LRCar1 needs only four bits to represent four directions. And 1 byte equals 8 bits, so LRCar1 takes 1 byte, so it takes 4 bytes and it obviously wastes 3 bytes of space. So how do we optimize this? Next we introduce the concept of bit-fields

1, a domain

struct LRCar2 { 
    BOOL front: 1; 
    BOOL back : 1; 
    BOOL left : 1; 
    BOOL right: 1; 
};
Copy the code

LRCar2andLRCar1In contrast, there’s one more after each member: 1.The number after the colon represents the memberHow many bits to occupy. After using bitfieldsLRCar2Only to take upfourThat is1 byteLet’s print and verify

2. Consortium

First observe the following structure and union comparison, first print the structure breakpointteacher1The assignment of each member variable can be found that during the assignment process of the structure, each member is not affected before and co-exists in the structure.And we find the complexteacher2In the assignment process, member variables are affected and mutually exclusive.Print the structures separatelyteacher1And a consortiumteacher2Address of each member variable. You can findThe structure of the bodyMember variables have their own memory space, whileA consortiumMember variables share the same memory space, soA consortiumMember variables are mutually exclusive.

conclusion

  • Structure (struct)In all variables are “coexisting” — the advantage is “tolerant”, comprehensive; The disadvantage is that the allocation of struct memory space is extensive, regardless of use, full allocation.
  • Union (union)Is that each variable is “mutually exclusive” — the disadvantage is not “inclusive” enough; But the advantage is that memory usage is more delicate and flexible, and also saves memory space

NonPointerIsa analysis

In the first articleAlloc exploreWe learn thatinitInstanceIsaThis step initializes the pointer associated class and follows throughinitIsaThis is initializationisaThe method ofisaisisa_tType.Look at the firstisa_t We found thatisa_tIt’s a union that containsbits,clsAnd there’s a structureISA_BITFIELD.

Generally in the process of representing a class address, there often appears an interesting noun callednonPointerIsa. A class is also an object, a pointer. We found that there’s a lot of information that can be stored on a class, Pointers to8 bytesnamelyA 64 - bitIf only one pointer is stored, it is a bit wasteful. Can we optimize it? You can have other things in a class besides Pointers, such as whether they are being released, reference counts, weak, associated objects, destructors, and so on, and that’s where it comes innonPointerIsa.nonPointerIsaIt’s no longer a simple pointer. How do you test this? We need to see itISA_BITFIELD ISA_BITFIELDFor different platformsarm64andx86Bit field Settings are different

  • nonpointer: indicates whether to enable pointer optimization for isa Pointers. 0: pure ISA pointer, 1: not only the address of the class object, ISA contains the class information, reference count of the object, and so on.
  • has_assoc: Indicates the flag of the associated object. Zero does not exist. One exists.
  • has_cxx_dtor: whether the object has a destructor for C++ or Objc. If there is a destructor, then the destructor logic needs to be done. If not, the object can be released more quickly.
  • shiftcls: Stores the value of the class pointer. With pointer optimization turned on, 33 bits are used to store class Pointers in the ARM64 architecture.
  • magic: used by the debugger to determine whether the current object is a real object or has no space to initialize.
  • weakly_referenced: indicates whether an object is or has been referred to an ARC weak variable. Objects without weak references can be released faster.
  • deallocating: indicates whether the object is freeing memory.
  • has_sidetable_rc: When the object reference technique is greater than 10, the variable is borrowed to store the carry.
  • extra_rcWhen representing the referential count value of the object, the referential count value is actually reduced by 1. For example, if the object’s reference count is 10, extra_rc is 9. If the reference count is greater than 10, has_sideTABLE_rc is used.

4. Isa derivation class

x/4gxPrint out thepAgain,p/xPrint out theLRPerson.class. We found a printoutisaAnd classes are not consistent. At this point isa should be associated with the class, but that doesn’t make any sense. The reason is that there are none& ISA_MASK.isaAnd the upper mask to get the class. becauseisaIn more than justclassThere’s a lot of other information that needs to go throughmaskTo get information about the class

Isa bit operation

Let’s say we don’t knowmaskAccording to the above analysis, it is clearisaBit-field distribution structure, class information inshiftclsAccording toAn operationIn order to getshiftcls.x86_64For example,shiftclsTake up44Bit, in the front3Bit, followed by17 (6 + 1 + 1 + 1 + 8)position

  • isaMoves to the right first3And emptyshiftclsThe front three
  • And then the left20And emptyshiftclsThe last 17 and the ones that just moved to the rightthree
  • And then finally to the right17Bits, reverts to the original location, and finally gets the class information. You can see it printed outLRPerson