Preamble: We have been exploring what objects are, understanding alloc, understanding how memory size is calculated, how bytes are aligned, and not really understanding what OC objects are. So today we’re going to analyze it

Analyzing OC Objects

1.1 Creating OC objects into the underlying code.cppanalysis

Create a LGPerson object and use the clang compiler to convert a.m file to a.cpp file for analysis

Note: Clang is an Apple-led, LLVM-based C/C++/Objective-C compiler

main.mcode:

#import <Foundation/ foundation.h > // create LGPerson class in main @interface LGPerson :NSObject @property(nonatomic,strong)NSString *name; @end @implementation LGPerson @end int main(int argc, Const char * argv[]) {LGPerson *p =[[LGPerson alloc]init]; p.name=@"lb"; return 0; }Copy the code

Use clang to compile main.m->main.cpp

CPP command: clang-rewrite-objc main.m -o main.cpp code: clang-rewrite-objc main.m -o main.cpp code:

// LGPerson extern "C" unsigned long OBJC_IVAR_$_LGPerson$_name; struct LGPerson_IMPL { struct NSObject_IMPL NSObject_IVARS; NSString *_name; };Copy the code

Parsing code: LGPerson is a structure at the bottom. Struct NSObject_IMPL NSObject_IVARS; Property, and then analyze the NSObject_IVARS found in the.cpp file

struct NSObject_IMPL {
 Class isa;
};
Copy the code

This can be interpreted as the underlying code for NSObject

conclusion

LGPerson inherits from NSObject so it’s easy to think of NSObject_IVARS as inheriting from NSObject’s member variable Class isa and by doing this analysis, an object isa structure underneath, and it always has a member variable of Class isa

Analysis of the isa

Before we analyze ISA, let’s understand what a union is.

Union is also composed of different data types, but its variables are mutually exclusive, and all the members occupy a segment of memory. Moreover, the common body adopts the memory overwrite technology, which can only store the value of one member at a time. If a value is assigned to a new member, the value of the original member will be overwritten

  • Weakness: Weak tolerance
  • Advantages: All members share a segment of memory, which makes memory usage more delicate and flexible and saves memory space
1.1 What is ISA?

“A pointer to the class definition of which this object is an instance”; This translates as a pointer to the class to which the current instance object belongs

This is not easy to understand.

Isa isa member variable of a Class isa. Isa isa member variable of a Class isa

1.2 Analysis of ISA

_class_createInstanceFromZone has obj->initIsa(CLS); When you click in, isa is initialized by isa_t and isa_t isa union

Because isa isa pointer to 8 bytes, and a byte is 8 bits, so there are 64 bits, it’s definitely a bit wasteful to use 64 bits only to store class addresses. The constructor member ISA_BITFIELD, which is a macro definition with two versions __arm64__ (for ios mobile) and __x86_64__ (for macOS). Here are some of their macro definitions. As shown in the figure below

1.3 ISA-64-bit Information Description
  • nonpointerThere are two values, representing custom classes, etc., accounted for1position
    • 0: pure ISA pointer
    • 1: Not only class object address, ISA contains class information, object reference count, etc
  • has_assocRepresents the associated object flag bit, accounting for1position
    • 0: no associated object
    • 1: An associated object exists
  • has_cxx_dtorIndicates whether the object hasC++/OCDestructor (similar todealloc),1If there is a bit destructor, then the destructor logic should be done. If there is no destructor, then the object can be freed faster
  • shiftclsThe value representing the pointer to the storage class (The address of the class), that is, class informationarm64A majority of the33Bit to turn on pointer optimization in casearm64In the architecture33Bits are used to store class Pointersx86_64A majority of the44position
  • magicThe 6-bit space used by the debugger to determine whether the current object is a real object or not initialized
  • weakly_refrencedIs whether an object is pointed to or has ever been pointed to oneARCObjects without weak references can be freed faster
  • deallocatingFlags whether the object is freeing memory
  • has_sidetable_rcIndicates that when the object reference count is greater than 10, the variable needs to be borrowed to store carry
  • extra_rc(extra reference count), which represents the reference count value of the object, actually the reference count value minus1If the object’s reference count is10, thenextra_rcfor9(This is just for example), in fact, the iPhone is a real phoneextra_rcIs the use of19Bit to store reference counts
1.4 Verify that ISA contains a true class pointing to this instance

We use LLDB to verify that the instance class can be obtained in the case of the X86_64 simulator

error: 'Plugin load' requires one argument (LLDB) p/x lgPerson. class $0 = 0x0000000100008170 LGPerson (LLDB) x/4gx p // Find the ISA address of the instance object 0x100605130:0x001D800100008175 0x0000000100004010 0x100605140: 0x0000000000000002 0x00000001002A5B98 (LLDB) p/x 0x001D800100008175 >> 3 // Move THE ISA address right 3 bits (long) $2 = 0x0003B0002000102E (LLDB) p/x $2 << 20 // Move ISA address 20 bits to the left (long) $3 = 0x0002000102e00000 (LLDB) p/x $3 >> 17 // Move ISA address 17 bits to the right (long) $4 = 0x0000000100008170 // Address is the same as class address (LLDB) Po $4 // Output to see if it is class LGPerson of this instance // verify that it is correctCopy the code

The author says:

Ps: If there is something wrong, I hope you can give more suggestions and comments. I’ll fix it. We’ll learn and we’ll improve.