2022-03-30 OC 底层学习随记

mac 12.2.1

xcode 13.2.1

objc4-838

1.alloc的流程

alloc ->

id

_objc_rootAlloc(Class cls)

{

    return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);

}

// Calls [cls alloc].

id

objc_alloc(Class cls)

{

    return callAlloc(cls, true/*checkNil*/, false/*allocWithZone*/);

}

static ALWAYS_INLINE id

callAlloc(Class cls, bool checkNil, bool allocWithZone=false)

{

#if __OBJC2__

    if (slowpath(checkNil && !cls)) return nil;

    if (fastpath(!cls->ISA()->hasCustomAWZ())) {

        return _objc_rootAllocWithZone(cls, nil);

    }

#endif

    // No shortcuts available.

    if (allocWithZone) {

        return ((id(*)(id, SEL, struct _NSZone *))objc_msgSend)(cls, @selector(allocWithZone:), nil);

    }

    return ((id(*)(id, SEL))objc_msgSend)(cls, @selector(alloc));

}

id

_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone __unused)

{

    // allocWithZone under __OBJC2__ ignores the zone parameter

    return _class_createInstanceFromZone(cls, 0, nil,

                                        OBJECT_CONSTRUCT_CALL_BADALLOC);

}

size = cls->instanceSize(extraBytes);

if (outAllocatedSize) *outAllocatedSize = size;

    id obj;

    if (zone) {

        obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size);

    } else {

        obj = (id)calloc(1, size);

    }


    if (!zone && fast) {

        obj->initInstanceIsa(cls, hasCxxDtor);

    } else {

        // Use raw pointer isa on the assumption that they might be

        // doing something weird with the zone or RR.

        obj->initIsa(cls);

    }




2.类结构原理

x/4gx  p/x  po

x/6gx LGPerson.class

8

cache_t cache; =16

p/x

//属性  VS 成员变量

@interface LGPerson : NSObject{

    NSString *subject;

}

@property(nonatomic,copy) NSString *name;

@property(nonatomic,copy) NSString *hobby;

-(void)satNB;

+(void)sayNB666;

@end

struct cache_t {

private:

    explicit_atomic<uintptr_t> _bucketsAndMaybeMask; //8

    union {

        struct {

            explicit_atomic<mask_t>    _maybeMask;  //4

#if __LP64__

            uint16_t                  _flags;  //2

#endif

            uint16_t                  _occupied;//2

        };

        explicit_atomic<preopt_cache_t *> _originalPreoptCache; //8

    };



union isa_t {

    isa_t() { }

    isa_t(uintptr_t value) : bits(value) { }

    uintptr_t bits;

private:

    // Accessing the class requires custom ptrauth operations, so

    // force clients to go through setClass/getClass by making this

    // private.

    Class cls;



struct objc_object {

private:

    isa_t isa;



struct objc_class : objc_object {

  objc_class(const objc_class&) = delete;

  objc_class(objc_class&&) = delete;

  void operator=(const objc_class&) = delete;

  void operator=(objc_class&&) = delete;

    // Class ISA;

    Class superclass;

    cache_t cache;            // formerly cache pointer and vtable

    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags

class_rw_t *data() const {

        return bits.data();

    }


  #define FAST_DATA_MASK          0x00007ffffffffff8UL


    class_rw_t* data() const {

        return (class_rw_t *)(bits & FAST_DATA_MASK);

    }


    struct class_rw_t {

    // Be warned that Symbolication knows the layout of this structure.

    uint32_t flags;

    uint16_t witness;

#if SUPPORT_INDEXED_ISA

    uint16_t index;

#endif

    explicit_atomic<uintptr_t> ro_or_rw_ext;

    Class firstSubclass;

    Class nextSiblingClass;




(lldb) x/4gx LGPerson.class

0x100008278: 0x00000001000082a0 0x0000000100801140

0x100008288: 0x0000000100ad4880 0x0002802c00000003

(lldb) p/x 0x100008278+0x20

(long) $1 = 0x0000000100008298

(lldb) p (class_data_bits_t *)0x0000000100008298

(class_data_bits_t *) $2 = 0x0000000100008298

(lldb) p $2->data()

(class_rw_t *) $3 = 0x0000000100ad4610

(lldb) p *$3

(class_rw_t) $4 = {

  flags = 2148007936

  witness = 1

  ro_or_rw_ext = {

    std::__1::atomic<unsigned long> = {

      Value = 4295000136

    }

  }

  firstSubclass = nil

  nextSiblingClass = 0x00007ff8428edac8

}

(lldb) p $3.properties()

(const property_array_t) $5 = {

  list_array_tt<property_t, property_list_t, RawPtr> = {

    = {

      list = {

        ptr = 0x00000001000081a8

      }

      arrayAndFlag = 4295000488

    }

  }

}

  Fix-it applied, fixed expression was:

    $3->properties()

(lldb) p $5.list

(const RawPtr<property_list_t>) $6 = {

  ptr = 0x00000001000081a8

}

(lldb) p $6.ptr

(property_list_t *const) $7 = 0x00000001000081a8

(lldb) p *$7

(property_list_t) $8 = {

  entsize_list_tt<property_t, property_list_t, 0, PointerModifierNop> = (entsizeAndFlags = 16, count = 2)

}

(lldb) p $8.get(0)

(property_t) $9 = (name = "name", attributes = "T@\"NSString\",C,N,V_name")

(lldb)

(lldb) p $8.get(1)

(property_t) $12 = (name = "hobby", attributes = "T@\"NSString\",C,N,V_hobby")

(lldb)

(lldb) p $3->methods()

(const method_array_t) $10 = {

  list_array_tt<method_t, method_list_t, method_list_t_authed_ptr> = {

    = {

      list = {

        ptr = 0x0000000100008090

      }

      arrayAndFlag = 4295000208

    }

  }

}

(lldb) p $10.list.ptr

(method_list_t *const) $11 = 0x0000000100008090

(lldb) p $10.list

(const method_list_t_authed_ptr<method_list_t>) $13 = {

  ptr = 0x0000000100008090

}

(lldb) p $13.ptr

(method_list_t *const) $14 = 0x0000000100008090

(lldb) p *$14

(method_list_t) $15 = {

  entsize_list_tt<method_t, method_list_t, 4294901763, method_t::pointer_modifier> = (entsizeAndFlags = 27, count = 7)

}

(lldb) p $15.get(0)

(method_t) $16 = {}

(lldb) p $15.get(0).big()

(method_t::big) $17 = {

  name = "satNB"

  types = 0x0000000100003f92 "v16@0:8"

  imp = 0x0000000100003ca0 (KCObjcBuild`-[LGPerson satNB])

}

(lldb) p $15.get(1).big()

(method_t::big) $18 = {

  name = "hobby"

  types = 0x0000000100003f8a "@16@0:8"

  imp = 0x0000000100003d30 (KCObjcBuild`-[LGPerson hobby])

}

(lldb) p $15.get(2).big()

(method_t::big) $19 = {

  name = "setHobby:"

  types = 0x0000000100003f9a "v24@0:8@16"

  imp = 0x0000000100003d60 (KCObjcBuild`-[LGPerson setHobby:])

}

(lldb) p $15.get(3).big()

(method_t::big) $20 = {

  name = "init"

  types = 0x0000000100003f8a "@16@0:8"

  imp = 0x0000000100003c10 (KCObjcBuild`-[LGPerson init])

}

(lldb) p $15.get(4).big()

(method_t::big) $21 = {

  name = "name"

  types = 0x0000000100003f8a "@16@0:8"

  imp = 0x0000000100003cd0 (KCObjcBuild`-[LGPerson name])

}

(lldb) p $15.get(5).big()

(method_t::big) $22 = {

  name = ".cxx_destruct"

  types = 0x0000000100003f92 "v16@0:8"

  imp = 0x0000000100003d90 (KCObjcBuild`-[LGPerson .cxx_destruct])

}

(lldb) p $15.get(6).big()

(method_t::big) $23 = {

  name = "setName:"

  types = 0x0000000100003f9a "v24@0:8@16"

  imp = 0x0000000100003d00 (KCObjcBuild`-[LGPerson setName:])

}

(lldb) p LGPerson.class

(Class) $1 = 0x0000000100008410

(lldb) p/x 0x0000000100008410+0x20

(long) $2 = 0x0000000100008430

(lldb) p (class_data_bits_t *)0x0000000100008430

(class_data_bits_t *) $3 = 0x0000000100008430

(lldb) p $3->data()

(class_rw_t *) $4 = 0x0000000100e59cb0

(lldb) p *$4

(class_rw_t) $5 = {

  flags = 2148007936

  witness = 1

  ro_or_rw_ext = {

    std::__1::atomic<unsigned long> = {

      Value = 4295000448

    }

  }

  firstSubclass = 0x00000001000083e8

  nextSiblingClass = 0x00007ff85597aac8

}

(lldb) p $5.ro()

(const class_ro_t *) $6 = 0x0000000100008180

(lldb) p * $6

(const class_ro_t) $7 = {

  flags = 388

  instanceStart = 8

  instanceSize = 32

  reserved = 0

  = {

    ivarLayout = 0x0000000100003eb4 "\U00000003"

    nonMetaclass = 0x0000000100003eb4

  }

  name = {

    std::__1::atomic<const char *> = "LGPerson" {

      Value = 0x0000000100003eb6 "LGPerson"

    }

  }

  baseMethods = {

    ptr = 0x00000001000081c8

  }

  baseProtocols = nil

  ivars = 0x0000000100008278

  weakIvarLayout = 0x0000000000000000

  baseProperties = 0x00000001000082e0

  _swiftMetadataInitializer_NEVER_USE = {}

}

(lldb) p $7.ivars

(const ivar_list_t *const) $8 = 0x0000000100008278

(lldb) p *$8

(const ivar_list_t) $9 = {

  entsize_list_tt<ivar_t, ivar_list_t, 0, PointerModifierNop> = (entsizeAndFlags = 32, count = 3)

}

(lldb) p $9.get(0)

(ivar_t) $10 = {

  offset = 0x00000001000083a8

  name = 0x0000000100003f31 "subject"

  type = 0x0000000100003f78 "@\"NSString\""

  alignment_raw = 3

  size = 8

}

(lldb) p $9.get(1)

(ivar_t) $11 = {

  offset = 0x00000001000083b0

  name = 0x0000000100003f39 "_name"

  type = 0x0000000100003f78 "@\"NSString\""

  alignment_raw = 3

  size = 8

}

(lldb) p $9.get(2)

(ivar_t) $12 = {

  offset = 0x00000001000083b8

  name = 0x0000000100003f3f "_hobby"

  type = 0x0000000100003f78 "@\"NSString\""

  alignment_raw = 3

  size = 8

}

(lldb) p $9.get(3)

(lldb) p $9.get(0).big()

(lldb) x/4gx LGPerson.class

0x1000082e8: 0x0000000100008310 0x0000000100801140

0x1000082f8: 0x0000000100f7c4d0 0x0002803400000003

(lldb) p/x 0x0000000100008310 & 0x00007ffffffffff8UL

(unsigned long) $1 = 0x0000000100008310

(lldb) po 0x0000000100008310

LGPerson

(lldb) p/x (class_data_bits_t *) 0x0000000100008330

(class_data_bits_t *) $3 = 0x0000000100008330

(lldb) p $3->data()

(class_rw_t *) $4 = 0x0000000100a232c0

(lldb) p *$4

(class_rw_t) $5 = {

  flags = 2684878849

  witness = 1

  ro_or_rw_ext = {

    std::__1::atomic<unsigned long> = {

      Value = 4311216753

    }

  }

  firstSubclass = nil

  nextSiblingClass = 0x00007ff8468abef0

}

(lldb) p $5.methods()

(const method_array_t) $6 = {

  list_array_tt<method_t, method_list_t, method_list_t_authed_ptr> = {

    = {

      list = {

        ptr = 0x0000000100008280

      }

      arrayAndFlag = 4295000704

    }

  }

}

(lldb) p $6.list

(const method_list_t_authed_ptr<method_list_t>) $7 = {

  ptr = 0x0000000100008280

}

(lldb) p $7.ptr

(method_list_t *const) $8 = 0x0000000100008280

(lldb) p *$8

(method_list_t) $9 = {

  entsize_list_tt<method_t, method_list_t, 4294901763, method_t::pointer_modifier> = (entsizeAndFlags = 27, count = 1)

}

(lldb) p $9.get(0).big()

(method_t::big) $10 = {

  name = "sayNB666"

  types = 0x0000000100003f47 "v16@0:8"

  imp = 0x0000000100003d00 (KCObjcBuild`+[LGPerson sayNB666] at main.m:46)

}

(lldb)

(lldb) p LGPerson.class

(Class) $1 = 0x0000000100008410

(lldb) p/x 0x0000000100008410+0x20

(long) $2 = 0x0000000100008430

(lldb) p (class_data_bits_t *)0x0000000100008430

(class_data_bits_t *) $3 = 0x0000000100008430

(lldb) p $3->data()

(class_rw_t *) $4 = 0x0000000100a232c0

(lldb) p *$4

(class_rw_t) $5 = {

  flags = 2684878849

  witness = 1

  ro_or_rw_ext = {

    std::__1::atomic<unsigned long> = {

      Value = 4311216753

    }

  }

  firstSubclass = nil

  nextSiblingClass = 0x00007ff8468abef0

}

(lldb) p $5.protocols()

(const protocol_array_t) $6{

}

(lldb) p $6.list

(const RawPtr<Protocol_list_t>) $7{

}

(lldb) p $7.ptr

(Protocol_list_t *const) $8

(lldb) p *$8

(Protocol_list_t)$9

(lldb) p $9.list[0]

(protocol_ref_t) $10

(lldb) p (protocol_t *)$10

(protocol_t *)$11

(lldb) p *$11

{{(struct objc_selector *)"init", "@16@0:8", (void *)_I_LGPerson_init},

{(struct objc_selector *)"satNB", "v16@0:8", (void *)_I_LGPerson_satNB},

@16@0:8

/*

1: @ id

2: 16 :占用内存

3: @ :id

4: 0: 从0 位置开始

5: : SEL

6: 8  从8 位置开始

*/

@property(nonatomic,copy) NSString *nickName;

@property(nonatomic,strong) NSString *name;

@property(atomic,strong) NSString *hobby;

static void _I_LGPerson_setNickName_(LGPerson * self, SEL _cmd, NSString *nickName) { objc_setProperty (self, _cmd, __OFFSETOFIVAR__(struct LGPerson, _nickName), (id)nickName, 0, 1); }

static void _I_LGPerson_setName_(LGPerson * self, SEL _cmd, NSString *name) { (*(NSString **)((char *)self + OBJC_IVAR_$_LGPerson$_name)) = name; }

static void _I_LGPerson_setHobby_(LGPerson * self, SEL _cmd, NSString *hobby) { (*(NSString **)((char *)self + OBJC_IVAR_$_LGPerson$_hobby)) = hobby; }

id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {

    if (offset == 0) {

        return object_getClass(self);

    }

    // Retain release world

    id *slot = (id*) ((char*)self + offset);

    if (!atomic) return *slot;


    // Atomic retain release world

    spinlock_t& slotlock = PropertyLocks[slot];

    slotlock.lock();

    id value = objc_retain(*slot);

    slotlock.unlock();


    // for performance, we (safely) issue the autorelease OUTSIDE of the spinlock.

    return objc_autoreleaseReturnValue(value);

}

static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)

{

    if (offset == 0) {

        object_setClass(self, newValue);

        return;

    }

    id oldValue;

    id *slot = (id*) ((char*)self + offset);

    if (copy) {

        newValue = [newValue copyWithZone:nil];

    } else if (mutableCopy) {

        newValue = [newValue mutableCopyWithZone:nil];

    } else {

        if (*slot == newValue) return;

        newValue = objc_retain(newValue);

    }

    if (!atomic) {

        oldValue = *slot;

        *slot = newValue;

    } else {

        spinlock_t& slotlock = PropertyLocks[slot];

        slotlock.lock();

        oldValue = *slot;

        *slot = newValue;       

        slotlock.unlock();

    }

    objc_release(oldValue);

}

void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL atomic, signed char shouldCopy)

{

    bool copy = (shouldCopy && shouldCopy != MUTABLE_COPY);

    bool mutableCopy = (shouldCopy == MUTABLE_COPY);

    reallySetProperty(self, _cmd, newValue, offset, atomic, copy, mutableCopy);

}

- (Class)class {

    return object_getClass(self);

}

+ (Class)superclass {

    return self->getSuperclass();

}

- (Class)superclass {

    return [self class]->getSuperclass();

}

+ (BOOL)isMemberOfClass:(Class)cls {

    return self->ISA() == cls;

}

- (BOOL)isMemberOfClass:(Class)cls {

    return [self class] == cls;

}

+ (BOOL)isKindOfClass:(Class)cls {

    for (Class tcls = self->ISA(); tcls; tcls = tcls->getSuperclass()) {

        if (tcls == cls) return YES;

    }

    return NO;

}

- (BOOL)isKindOfClass:(Class)cls {

    for (Class tcls = [self class]; tcls; tcls = tcls->getSuperclass()) {

        if (tcls == cls) return YES;

    }

    return NO;

}

// Calls [obj class]

Class

objc_opt_class(id obj)

{

#if __OBJC2__

    if (slowpath(!obj)) return nil;

    Class cls = obj->getIsa();

    if (fastpath(!cls->hasCustomCore())) {

        return cls->isMetaClass() ? obj : cls;

    }

#endif

    return ((Class(*)(id, SEL))objc_msgSend)(obj, @selector(class));

}

// Calls [obj isKindOfClass]

BOOL

objc_opt_isKindOfClass(id obj, Class otherClass)

{

#if __OBJC2__

    if (slowpath(!obj)) return NO;

    Class cls = obj->getIsa();

    if (fastpath(!cls->hasCustomCore())) {

        for (Class tcls = cls; tcls; tcls = tcls->getSuperclass()) {

            if (tcls == otherClass) return YES;

        }

        return NO;

    }

#endif

    return ((BOOL(*)(id, SEL, Class))objc_msgSend)(obj, @selector(isKindOfClass:), otherClass);

}

objc_opt_isKindOfClass

        BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];      //1

        BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];    //0

        BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];      //0

        BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];    //0

        NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);

        BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];      //1

        BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];    //1

        BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];      //1

        BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];    //1

        NSLog(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);

struct cache_t {

private:

    explicit_atomic<uintptr_t> _bucketsAndMaybeMask;

    union {

        struct {

            explicit_atomic<mask_t>    _maybeMask;

#if __LP64__

            uint16_t                  _flags;

#endif

            uint16_t                  _occupied;

        };

        explicit_atomic<preopt_cache_t *> _originalPreoptCache;

    };


(lldb) p/x pClass

(Class) $0 = 0x0000000100008318

(lldb) p (cache_t *)0x0000000100008318

(cache_t *) $1 = 0x0000000100008318

(lldb) p *$1

(cache_t) $2 = {

  _bucketsAndMaybeMask = {

    std::__1::atomic<unsigned long> = {

      Value = 4295000896

    }

  }

  = {

    = {

      _maybeMask = {

        std::__1::atomic<unsigned int> = {

          Value = 8393024

        }

      }

      _flags = 1

      _occupied = 0

    }

    _originalPreoptCache = {

      std::__1::atomic<preopt_cache_t *> = {

        Value = 0x0000000100801140

      }

    }

  }

}

(lldb) p $2._bucketsAndMaybeMask

(explicit_atomic<unsigned long>) $3 = {

  std::__1::atomic<unsigned long> = {

    Value = 4295000896

  }

}

(lldb) p $2._maybeMask

(explicit_atomic<unsigned int>) $4 = {

  std::__1::atomic<unsigned int> = {

    Value = 8393024

  }

}

(lldb) p $2._originalPreoptCache

(explicit_atomic<preopt_cache_t *>) $5 = {

  std::__1::atomic<preopt_cache_t *> = {

    Value = 0x0000000100801140

  }

}

(lldb) p $5.value()

error: <user expression 6>:1:4: no member named 'value' in 'explicit_atomic<preopt_cache_t *>'

$5.value()

~~ ^

(lldb) p $2.buckets()

(bucket_t *) $6 = 0x0000000100008340

(lldb) p *$6

(bucket_t) $7 = {

  _sel = {

    std::__1::atomic<objc_selector *> = "\xf0\U00000010\x80" {

      Value = "\xf0\U00000010\x80"

    }

  }

  _imp = {

    std::__1::atomic<unsigned long> = {

      Value = 4303360240

    }

  }

}

(lldb) p [per satNB]

2022-03-23 17:22:40.314152+0800 KCObjcBuild[7258:92946] satNB

(lldb) p/x pClass

(Class) $8 = 0x0000000100008318

(lldb) p (cache_t *)0x0000000100008318

(cache_t *) $9 = 0x0000000100008318

(lldb) p *$9

(cache_t) $10 = {

  _bucketsAndMaybeMask = {

    std::__1::atomic<unsigned long> = {

      Value = 4295000896

    }

  }

  = {

    = {

      _maybeMask = {

        std::__1::atomic<unsigned int> = {

          Value = 8393024

        }

      }

      _flags = 1

      _occupied = 0

    }

    _originalPreoptCache = {

      std::__1::atomic<preopt_cache_t *> = {

        Value = 0x0000000100801140

      }

    }

  }

}

(lldb) p $10.buckets()

(bucket_t *) $11 = 0x0000000100008340

(lldb) p *$11

(bucket_t) $12 = {

  _sel = {

    std::__1::atomic<objc_selector *> = "\xf0\U00000010\x80" {

      Value = "\xf0\U00000010\x80"

    }

  }

  _imp = {

    std::__1::atomic<unsigned long> = {

      Value = 4303360240

    }

  }

}

(lldb) p $10.buckets()[1]

(bucket_t) $13 = {

  _sel = {

    std::__1::atomic<objc_selector *> = (null) {

      Value = (null)

    }

  }

  _imp = {

    std::__1::atomic<unsigned long> = {

      Value = 246518237888512

    }

  }

}

(lldb) p $12.sel()

(SEL) $14 = "\xf0\U00000010\x80"

(lldb) p $13.sel()

(SEL) $15 = ""

(lldb) p $13.imp()

error: <user expression 18>:1:9: too few arguments to function call, expected 2, have 0

$13.imp()

~~~~~~~ ^

note: 'imp' declared here

(lldb) p $12.imp()

error: <user expression 19>:1:9: too few arguments to function call, expected 2, have 0

$12.imp()

~~~~~~~ ^

note: 'imp' declared here

(lldb) p $12.imp(nil,pClass)

(IMP) $16 = 0x00000000008093e8 (0x00000000008093e8)

(lldb) p $13.imp(nil,pClass)

(IMP) $17 = 0x0000e03400008318 (0x0000e03400008318)

(lldb) p *$14

(SEL) $18 = "\xf0\U00000010\x80"

(lldb)


typedef uint32_t mask_t;

struct kc_bucket_t {

    SEL _sel;

    IMP _imp;

};

struct kc_cache_t {

    struct kc_bucket_t *_bukets;

  // uintptr_t _bucketsAndMaybeMask;

        mask_t    _maybeMask;

        uint16_t    _flags;

        uint16_t  _occupied;

};

struct kc_class_data_bits_t {

    uintptr_t bits;

};

struct kc_objc_class{

    Class isa;

    // Class ISA;

    Class superclass;

    struct kc_cache_t cache;            // formerly cache pointer and vtable

    struct kc_class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags


};

LGPerson *per = [[LGPerson alloc]init];

        Class pClass = per.class;

        [per satNB];


      //

        struct kc_objc_class *kc_class =(__bridge struct kc_objc_class *) (pClass);

        NSLog(@"%hu--%u",kc_class->cache._occupied,kc_class->cache._maybeMask);

        //1--7


        for (mask_t i = 0; i< kc_class->cache._maybeMask;i++ ) {

            struct kc_bucket_t buckets = kc_class->cache._bukets[i];

            NSLog(@"%@--%p",NSStringFromSelector(buckets._sel),buckets._imp);

        }

        /*

        2022-03-23 18:01:38.736487+0800 KCObjcBuild[7745:122662] 1--7

        2022-03-23 18:01:38.736558+0800 KCObjcBuild[7745:122662] (null)--0x0

        2022-03-23 18:01:38.736599+0800 KCObjcBuild[7745:122662] (null)--0x0

        2022-03-23 18:01:38.736865+0800 KCObjcBuild[7745:122662] satNB--0xb4d0

        2022-03-23 18:01:38.736913+0800 KCObjcBuild[7745:122662] (null)--0x0

        2022-03-23 18:01:38.736950+0800 KCObjcBuild[7745:122662] (null)--0x0

        2022-03-23 18:01:38.736985+0800 KCObjcBuild[7745:122662] (null)--0x0

        2022-03-23 18:01:38.737019+0800 KCObjcBuild[7745:122662] (null)--0x0

        */


void cache_t::insert(SEL sel, IMP imp, id receiver)

{

    printf("======== %s- %p --%p \n",(char*)sel,imp,receiver);




    mask_t newOccupied = occupied() + 1;

    unsigned oldCapacity = capacity(), capacity = oldCapacity;



    if (sel == @selector(say1)) {

        bucket_t *kc_b = buckets();

        for (unsigned i =0; i< oldCapacity; i++) {

            SEL kc_sel = kc_b[i].sel();

            IMP kc_imp = kc_b[i].imp(kc_b, nil);


            printf("%p- %p - %p \n",kc_sel,kc_imp,&kc_b[i]);

        }

        printf("is-------%p- %u - %u --%u \n",kc_b,capacity,newOccupied,oldCapacity);


    }





(lldb) p [per say1]   

======== respondsToSelector:- 0x1007e87b0 --0x100a3ba50

======== class- 0x1007e8470 --0x100a3ba50

======== say1- 0x100003730 --0x100a3ba50

2022-03-29 17:38:46.191989+0800 KCObjcBuild[7271:188335] -[LGPerson say1]

======== retain- 0x1007e9140 --0x100e1cca0

======== release- 0x1007e92c0 --0x100e1cca0

======== dealloc- 0x1007e9400 --0x100e1cca0

(lldb) p [per say1]

======== respondsToSelector:- 0x1007e8770 --0x100a0e130

======== class- 0x1007e8430 --0x100a0e130

======== say1- 0x100003730 --0x100a0e130

0x0- 0x0 - 0x100e36b70

0x0- 0x0 - 0x100e36b80

0x0- 0x0 - 0x100e36b90

0x0- 0x0 - 0x100e36ba0

0x0- 0x0 - 0x100e36bb0

0x7ff81f2be2e5- 0x7e0020 - 0x100e36bc0

0x0- 0x0 - 0x100e36bd0

0x1- 0x100e36b70 - 0x100e36be0

is-------0x100e36b70- 8 - 2 --8

2022-03-29 17:45:56.407530+0800 KCObjcBuild[7319:191889] -[LGPerson say1]

======== retain- 0x1007e9100 --0x100e37220

======== release- 0x1007e9280 --0x100e37220

======== dealloc- 0x1007e93c0 --0x100e37220

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • OC底层原理探索文档汇总[https://www.jianshu.com/p/04883ea4f5aa] 整体分析...
    iOS之文一阅读 621评论 0 1
  • 在OC中我们经常考到alloc, 那alloc究竟为我们做了什么? 1.initInstanceIsa计算申请的内...
    麟枫_Jack阅读 262评论 0 2
  • 关联对象补充 上节课我们在探索关联对象设置流程,在_object_set_associative_referenc...
    浅墨入画阅读 277评论 0 1
  • 前言 在《类的探究分析》[https://www.jianshu.com/p/b2976dc9229e]一文中详细...
    冼同学阅读 685评论 0 3
  • 怎样将oc代码反编译成C和C++代码?使用xcode内置的LLVM的前端编译器clang,这样生成的代码并不完全是...
    东也_阅读 1,899评论 4 14