This is the 4th day of my participation in the August More Text Challenge
A,isa
Analyze to metaclass
In the previousIsa analysisAnd we analyze thatObject isa & ISA_MASK
getLRPerson
Class, is there any in that classisa
It is, the classisa
What does it point to?Pick up from the previous chapter on thisLRPerson
The class againx/4gx
View memory and print outClass isa & ISA_MASK
I also gotLRPerson
Class. That is to say,0x0000000100008388
0x0000000100008360
All point toLRPerson
.
You can see that the class also opens up memory for ISA and other information. So let’s guess: classes can open up memory just like objects, and there is more than one class. Let’s try to verify that
Check out the following code print:You can see that the class object points to the same memory address0x100008388
, that topClass isa & ISA_MASK
To get the0x0000000100008360
What is it?
At this point with the aid ofMachOView
View executable filesYou can see in the symbol table that there’s aMETACLASS
And this isThe metaclass
.Metaclasses are system-generated and compiled
.
The flow can be analyzed here: object ISA -> class ISA -> metaclass
Second,isa
Go bitmap and inheritance chain
1.isa
Walk a
The above analysis shows thatThe metaclass
, thenIsa metaclass
What about the process?throughlldb
Step by step analysis of the print, observe the following conclusions:
Object the isa
->class
Class isa
->The metaclass
The metaclass isa
->A metaclass
A metaclass isa
->A metaclass
The root class isa
->A metaclass
Through the code verification:
// NSObject instance object
NSObject *object1 = [NSObject alloc];
/ / NSObject class
Class cass = object_getClass(object1);
/ / NSObject metaclass
Class metaClass = object_getClass(class);
// NSObject root metaclass
Class rootMetaClass = object_getClass(metaClass);
// NSObject Root metaclass
Class rootRootMetaClass = object_getClass(rootMetaClass);
NSLog(@"\n-%p instance object \n-%p class \n-%p metaclass \n-%p root metaclass \n-%p root metaclass",object1,class,metaClass,rootMetaClass,rootRootMetaClass);
Copy the code
Get the print result:
-0x10104e840Instance objects-0x100357140 类
-0x1003570f0The metaclass-0x1003570f0A metaclass-0x1003570f0Spikes metaclassCopy the code
Combined with analysisisa
Walk the bitmap:
2,isa
Inheritance chain
In OC, classes are inherited, so is the metaclass root metaclass inherited? To explore, first create a class LRTeacher inherited from LRPerson, and then observe the following code print
/ / LRPerson metaclass
Class pMetaClass = object_getClass(LRPerson.class);
Class psuperClass = class_getSuperclass(pMetaClass);
NSLog(@"LRPerson metaclass parent: %@ - %p",psuperClass,psuperClass);
// LRTeacher -> LRPerson -> NSObject
// The metaclass also has an inheritance chain
Class tMetaClass = object_getClass(LRTeacher.class);
Class tsuperClass = class_getSuperclass(tMetaClass);
NSLog(@"LRTeacher metaclass parent: %@ - %p",tsuperClass,tsuperClass);
// NSObject root class special case
Class nsuperClass = class_getSuperclass(NSObject.class);
NSLog(@" Parent of root class: %@ - %p",nsuperClass,nsuperClass);
// Root metaclass -> NSObject
Class rnsuperClass = class_getSuperclass(object_getClass(NSObject.class));
NSLog(@" Parent of the root metaclass: %@ - %p",rnsuperClass,rnsuperClass);
Copy the code
The print result is as follows:
The parent of the LRPerson metaclass:NSObject - 0x1003570f0LRTeacher metaclass parent: LRPerson -0x100008360Parent of the root class :(null) -0x0The parent of the root metaclass:NSObject - 0x100357140
Copy the code
According to the printed results:
LRPerson metaclass
Inheritance inNSObject metaclass
namelyA metaclass
LRTeacher metaclass
Inheritance inLRPerson metaclass
NSObject root class
Inheritance innil
NSObject metaclass
Inheritance inNSObject root class
Through the above analysisisa
Bitmaps and inheritance chains combine to create a classic picture on apple’s official website
Third, the structure of the source analysis class
Object memory
There areisa
There areMember variables
, thenThe memory of a class
What’s in it? We can see the root of the class in the source codeobjc_class
Is a structure. objc_class
There are four member variables in the structure: hidden member variablesISA
Inheritance inobjc_object
,superclass
The parent class,cache
,bits
. We’re already familiar with the first two, socache
andbits
What is it?
Class_rw_t contains the protocol for method attributes and so on
struct class_rw_t {
...
const method_array_t methods() const{... }const property_array_t properties() const{... }const protocol_array_t protocols() const {...}
}
Copy the code
Now that we’re just going to objc_class, how do we get this memory data from the class?
Pointer and memory translation
It is not known how to get the structure of the current memory, so let’s look at Pointers and memory pans.
// Common pointer
int a = 10;
int b = 10;
NSLog(@"%d -- %p",a,&a);
NSLog(@"%d -- %p",b,&b);
// Object pointer
LRPerson *p1 = [LRPerson alloc];
LRPerson *p2 = [LRPerson alloc];
NSLog(@"%@ -- %p",p1,&p1);
NSLog(@"%@ -- %p",p2,&p2);
Copy the code
Observe the above code and get the print result as follows:
10 -- 0x7ffeefbff4cc
10 -- 0x7ffeefbff4c8
<LRPerson: 0x100714f90> -- 0x7ffeefbff4c0
<LRPerson: 0x10070e660> -- 0x7ffeefbff4b8
Copy the code
The common pointer points to the same memory space, but the two addresses are different. That’s the value copy. The addresses of two object Pointers are different, pointing to different memory space.
Look at thePointer to an array
// Array pointer
int c[4] = {1.2.3.4};
int *d = c;
NSLog(@"%p - %p - %p",&c,&c[0],&c[1]);
NSLog(@"%p - %p - %p",d,d+1,d+2);
Copy the code
Print result:
The address of &c[0] is the same as that of the first element. Memory addresses are contiguous and differ by 4 bytes, indicating that the current element type is 4 bytes. The pointer D +1 represents a shift by one step (the size of the current element type), in this case by 4 bytes, or by 8 bytes if the array is a pointer or object.
According to the analysis conclusion, we know that we can do the value operation through the translation of the pointer address, code verificationPrint result:
1
2
3
4
Copy the code
With this verification, can the class also fetch data by memory translation?
Fifth, class structure memory calculation
Print to view the memory status of the classAccording to the previous source code analysis class structure, you can know the first address0x0000000100008360
isisa
It should be followed bysuperclass
(Structure pointer is 8 bytes), verified in the screenshot0x0000000100357140
forNSObject
. The following iscache
andbits
? Let’s start todaybits
And subsequent research of separate chapterscache
.
From the structure of the classisa
andsuperclass
Are allClass
The type is the structure pointer8 bytes
, want to pan through memory tobits
The first thing to knowcache
The size of the. Follow up belowcache_t
Source: cache_t
Is a structure whose size depends on the size of its internal member variables. We found thatcache_t
There are a lot of things in the structure, wheremethods
In the method area,The global variable
Does not occupy the structure in the global region
struct cache_t {
private:
explicit_atomic<uintptr_t> _bucketsAndMaybeMask;/ / 8 bytes
union {
struct {
explicit_atomic<mask_t> _maybeMask;/ / 4 bytes
#if __LP64__
uint16_t _flags;/ / 2 bytes
#endif
uint16_t _occupied;/ / 2 bytes
};
explicit_atomic<preopt_cache_t *> _originalPreoptCache;/ / 8 bytes}; . }Copy the code
The explicit_atomic
is a generic type whose true size depends on the uintptr_t that is 8 bytes. Originalpreoptcache = _originalPreoptCache = _originalPreoptCache = _originalPreoptCache = _originalPreoptCache
socache_t
Size of the16 bytes
.
To get herebits
Needs to be offset from the first address of the class32 bytes
namely0x20
Isa (8) + Superclass (8) + cache (16)). The first addressOffset 0 x20
After the strong toclass_data_bits_t *
You get the typebits
The address of the
Vi.lldb
Analyze the attributes of the class
The above has been obtainedbits
Where we areobjc_class
See the following line of code in the structureTry to getbits.data()
, because it isPointer to the
Need to use->
callWe found that$2->data()
gotclass_rw_t *
Type variable. Check it again$3
Content found not previously mentionedmethods
attribute
agreement
And so on. You have to go through$4.properties()
To obtain,lldb
The analysis process is as follows:
Seven,lldb
Methods for analyzing classes
The above analysis of classattribute
, change theLRPerson
, add some properties and methods
Continue through thelldb
Methods for analyzing classesWhen analyzing methods, reducemethod_list_t
Later, byget(index)
Unable to get methods, this is different from properties
struct property_t {
const char *name;
const char *attributes;
};
struct method_t {
...
struct big {
SEL name;
const char*types; MethodListIMP imp; }; . public: big &big()const{ ASSERT(! isSmall());return* (struct big *)this; }... };Copy the code
The property_t structure has two member variables that match the printed information, and the method_t structure has a big structure, so trying to print the big structure gives us the information we want to see.
reductionmethod_list_t
And then you can seecount = 5
, that is, there are 5 methods, print these 5 methods:And what we found is thatsaySomething
andhobby
,name
theget
set
Method,LRPerson
The class methodsay666
But it didn’t becauseClass method
Stored in theThe metaclass
In theMethods list
In the water.
Eight,lldb
Analyze the protocol of the class
Write an agreement,LRPerson
Methods for complying with and implementing the protocol
inclass_rw_t
I have one of these structuresprotocols
methods
lldb
Analyze the protocol of the classWhen it get toprotocol_list_t
Discovery and propertiesproperty_list_t
, methods,method_list_t
The structure is different. To viewprotocol_list_t
The structure of the body protocol_list_t
In the structurelist[0]
forprotocol_ref_t
Type, get toprotocol_ref_t
After the direct strong turnprotocol_t
Print out the details to seeinstanceMethods
.instanceMethods
The list of methods for the protocol, and in the list of methods we find the methods for the protocol we wrote earlier.