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 will
cover
Values of other variables. - All the variables of the union
Shared memory
Variables 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 a
C语言、C++、Objective-C
A lightweight compiler for the language, written by Apple - Clang is mainly used to compile source files into underlying files, such as files
main.m
File 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:
Class
The type is actuallyobjc_class
Pointer to a structure of type,objc_class
Is the underlying implementation of all classes. Here’s our guessisa
There may be important associations with class information.NSObject
The bottom layer of is actuallyobjc_object
In OC, basically all objects inherit NSObject, but the real underlying implementation isobjc_object
Struct type of. whileobcj_object
Is 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 NSObject
isa
- There’s only one member variable in NSObject that is
isa
isa
Association 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 pointer0
Represents pure ISA,1
Indicates that additional information is includedhas_accos
: Whether to associate objects,0
Indicates no association,1
Means associatedhac_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 releasedshiftcls
: class, pointer address, enable pointer optimization in casearm64
In the architecture33
Bits are used to store class Pointers,x86_64
The architecture of44
positionmagic
The debugger determines that the current object isThe real object
orNo initialization
The space ofweakly_referenced
: Whether the object is or has been referred to an ARC weak variable. Objects without weak references can be freed fasterunused
: Whether to be releasedhas_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 carryextra_rc
: The referential count value of this object, actually the referential count value minus1
For example, if the object’s reference count is10
, thenextra_rc
for9
, if greater than10
I need to use the one abovehas_sidetable_rc
Isa structure Summary
isa
Divided intononpointer
The types and thenonpointer
. nonnonpointer
The type is just a pure pointer,nonpointer
It also contains information about classesisa
Is 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 objectisa
Pointers, lots of themisa
It 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 speakisa
Pointer memory is fully utilized.