The preparatory work
After the OC object calls a method, the method information is stored in the class cache for the next quick call. To prepare, follow the property-member-methods of the # OC class memory layout. Here we just take the underlying structure of the class. The cache of a class is the cache member, so we’ll focus on cache_t;
Struct objc_class (struct objc_object); struct objc_object (object); obviously
Objc source code version: 818.2
struct objc_class { isa_t isa; // 8 bytes Class superclass; // 8 bytes cache_t cache; // 16 bytes class_data_bits_t bits; // there are too many methods to define... class_rw_t *data() const { return bits.data(); }}Copy the code
Simplified cache_T structure, the source code has various architectural judgments and so on. The buckets() method is used to fetch an array of storage methods. The array is of type bucket_T, and bucket_T is just two properties, sel and IMP of the method so bucket_t structure is important;
struct cache_t { uintptr_t _bucketsAndMaybeMask; mask_t _maybeMask; uint16_t _flags; uint16_t _occupied; Struct buckets() const; };Copy the code
struct bucket_t { uintptr_t _imp; SEL _sel; SEL IMP rawImp(objc_class * CLS) const {} IMP IMP (bucket_t *base, bucket_t *base, bucket_t *base, bucket_t *base) Class cls) const { } };Copy the code
Look at the class cache
All preparations continue, let’s debug a wave;
- Before we call the method, let’s take a look
cache
._occupied = 0
There’s obviously no data yet. - Continue down one step break point. call
sayNB
This method — and then we’ll look at itcache
At this time,_occupied = 1
, indicating that a method has been cached. - And then let’s look for this cached method and see if it’s the one we’re calling
sayNB
This method, after a debug print, we confirm that it’s what we’re callingsayNB
This method. - One step further down the breakpoint, call
sayHello
This method — and then we’ll look at itcache
At this time,_occupied = 2
“, indicating that both methods are already cached. - And then let’s look for this cached method and see if it’s the one we’re calling
sayHello
This method. this is exactly what we were looking for.
conclusion
As a result of our debugging efforts, we believe that we have a clear understanding of the class cache. After a method is called, it is stored in the cache. In this way, the next time it is called, it can be directly found and called in the cache without searching the method list and loading it into the memory, which improves efficiency and performance.