Before we get to the nature of objects, let’s start with a bit of code as usual.

Struct1 takes 3 bytes, struct2 only takes 1 byte. What is this operation?

This is the bitfield, buddy!

A domain

It is a waste of memory to use an entire byte (1 byte = 8 bits) for some information (male/female) stored in a memory procedure that actually requires only 1 bit. To avoid this waste of memory, we have bitfields.

A bitfield represents the arrangement of binary bits from right to left. For example, the memory layout of each variable of struct1 and struct2 is as follows:

A consortium

The data type corresponding to a structure is a union, also known as a community. Let’s see what a union is through an example.

From the code result you get the result:

  • Changing one of the variables in the union willcoverValues of other variables.
  • All the variables of the unionShared memoryVariables are mutually exclusive. So the union is also called the community

The advantage of union is more memory saving, the disadvantage is not enough inclusive!!

Nature of object

Before getting into the nitty grata, let’s look at the Clang compiler.

  • Clang is aC语言、C++、Objective-CA lightweight compiler for the language, written by Apple
  • Clang is mainly used to compile source files into underlying files, such as filesmain.mFile compiled intomain.cpp, main.o, or an executable file. It is convenient for us to observe the logical structure of the bottom layer and explore the bottom layer.

Clang terminal compiles commands

//UIKit error clang-x objective-c-rewrite-objc-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk main.m // xcrun-sdk iphonesimulator clang-arch arm64-rewrite-objc main.m -o Iphoneos clang-arch arm64-rewrite-objc main.m -o main-arm64.cpp //4, compile xcrun-sdk iphoneos clang-arch arm64-rewrite-objc main.m -o main-arm64.cppCopy the code

Compile the following code through Clang:

{
    NSString * height;
}
@property(nonatomic,  copy)NSString   *LWname;
@property(nonatomic,assign)NSInteger  age;
@end

@implementation LWPerson

@end

int main(int argc, char * argv[]) {
  
    @autoreleasepool {
    }
    return 0;
}
Copy the code

Compile result:

#define _REWRITER_typedef_NSObject
typedef struct objc_object NSObject;
typedef struct {} _objc_exc_NSObject;
#endif

struct NSObject_IMPL {
	Class isa;
};

extern "C" unsigned long OBJC_IVAR_$_LWPerson$_LWname;
extern "C" unsigned long OBJC_IVAR_$_LWPerson$_age;
struct LWPerson_IMPL {
	struct NSObject_IMPL NSObject_IVARS;
	double  height;
	NSString *_LWname;
	NSInteger _age;
};

// @property(nonatomic, copy)NSString *LWname;
// @property(nonatomic,assign)NSInteger age;
/* @end */

// @implementation LWPerson

Copy the code

The compilation results are analyzed as follows:

  • ClassThe type is actuallyobjc_classPointer to a structure of type,objc_classIs the underlying implementation of all classes. Here’s our guessisaThere may be important associations with class information.
  • NSObjectThe bottom layer of is actuallyobjc_objectIn OC, basically all objects inherit NSObject, but the real underlying implementation isobjc_objectStruct type of. whileobcj_objectIs the member variable structure ofClass isa.

So, what our object actually looks like:

  • The essence of an object is a structure
  • The ISA for Person is inherited from NSObjectisa
  • There’s only one member variable in NSObject that isisa

isaAssociation class

Alloc –> _objc_rootAlloc –> callAlloc –> _objc_rootAllocWithZone –> _class_createInstanceFromZone The breakpoint is obj->initInstanceIsa, enter obj->initInstanceIsa inline void breakpoint to enter initIsa

We found that isa’s structure type is ISA_t, go isa_T

From this source we can know:

The isa structure is isa_t, and you can see that the actual internal content storage format is ISA_BITFIELD.

In addition to containing Pointers, ISA also stores a lot of other information in the form of bitfields. The specific information can be viewed directly with bitfields.

  • nonpointer: Whether to optimize the ISA pointer0Represents pure ISA,1Indicates that additional information is included
  • has_accos: Whether to associate objects,0Indicates no association,1Means associated
  • hac_cxx_dtor: Whether there is a destructor. If there is a destructor, the destructor logic needs to be performed. If there is no destructor, the object is released
  • shiftcls: class, pointer address, enable pointer optimization in casearm64In the architecture33Bits are used to store class Pointers,x86_64The architecture of44position
  • magicThe debugger determines that the current object isThe real objectorNo initializationThe space of
  • weakly_referenced: Whether the object is or has been referred to an ARC weak variable. Objects without weak references can be freed faster
  • unused: Whether to be released
  • has_sidetable_rc: Whether there are other list stores. When the object reference count is greater than 10, we need to borrow this variable to store carry
  • extra_rc: The referential count value of this object, actually the referential count value minus1For example, if the object’s reference count is10, thenextra_rcfor9, if greater than10I need to use the one abovehas_sidetable_rc

Isa structure Summary

  • isaDivided intononpointerThe types and thenonpointer. nonnonpointerThe type is just a pure pointer,nonpointerIt also contains information about classes
  • isaIs the union + bitfield way to store information. The advantage of this approach is that it saves a lot of memory. Everything is an object, so long as it is an objectisaPointers, lots of themisaIt takes up a lot of memory, and the union saves some memory by sharing a piece of memory, and the bit domain stores information on the basis of saving memory, so to speakisaPointer memory is fully utilized.