preface
For iOS development, we all know that the essence of iOS object isa structure, which contains isa, superclass, cache, bits and a series of contents; We’ve looked at isa, superclass, and bits, but let’s look at what cache does.
One: What is cache?
First we first through the object source code to understand the basic information of the cache;
As you can see from the above figure, the underlying structure of the object is a cache type called cache_t. We can also see that to obtain a cache, we can use the memory address of the generated object to obtain the cache 16 bits cheaper. The diagram below:
Cache_t exists as a structure at the bottom of the page. From its literal meaning we can see that cache_t is used for caching. Since it is a cache, there must be insertions, deletions, and so on. From the source structure of cache_t, we can see the following code:
We see _IMP and _sel in the structure of bucket_t. Does that make sense?
At this point we have an overview of cache_t’s data structure:
Cache_t validation
Let’s verify with some code that cache_t is really structured like this. First of all, we print the data obtained above
From the print result, we can see that we can’t access the content inside, which can infer that there may not be the content we want. So how do we do that?
After analyzing the cache_t source code, we can see the following:
There is a pointer to a bucket structure in the source code, which is probably what we want:
We don’t get anything valuable from LLDB printing, why is that? After analysis, cache_t caches methods that were called, but were not called when we were debugging; Now let’s look at what the data looks like after the method is called;
In the face of this answer a face meng force, clearly is called this method, why we still do not want it? Buckets are a literal element. Buckets store elements according to the hash function. Hash does not start at 0, array starts at 0
Now we print p $15.sel() to get the result we want below:
So how do we get saySomething’s imp?
Bucket_t = bucket_t; bucket_t = bucket_t; bucket_t = bucket_t; bucket_t = bucket_t; bucket_t = bucket_t;
We finally see what we want to see; The above content is we have the source code to explore, so if we do not have the source code when we can still get the content we want? Sure, here’s what you need to do:
Through the above way, in accordance with the requirements of the system to customize the structure, and then in the code to call the same can get the content we want;
Three: Write at the end
One last word about cache_t’s memory allocation rules for caching methods. Cache_t allocates memory by three quarters. That is, cache_t initially allocates a certain amount of content, caches methods when they are called, and caches methods when they are larger than three quarters. The current memory will be expanded by 2. Specific inquiry method next time in say!