isa探索

作者: king_jensen | 来源:发表于2019-02-23 15:19 被阅读2次

打开objc-750源码,找到结构体objc_object,直接对isa源码分析。

struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};
struct objc_object {
private:
    isa_t isa;

public:

    // ISA() assumes this is NOT a tagged pointer object
    Class ISA();

    // getIsa() allows this to be a tagged pointer object
    Class getIsa();

    // initIsa() should be used to init the isa of new objects only.
    // If this object already has an isa, use changeIsa() for correctness.
    // initInstanceIsa(): objects with no custom RR/AWZ
    // initClassIsa(): class objects
    // initProtocolIsa(): protocol objects
    // initIsa(): other objects
    void initIsa(Class cls /*nonpointer=false*/);
    void initClassIsa(Class cls /*nonpointer=maybe*/);
    void initProtocolIsa(Class cls /*nonpointer=maybe*/);
    void initInstanceIsa(Class cls, bool hasCxxDtor);

    // changeIsa() should be used to change the isa of existing objects.
    // If this is a new object, use initIsa() for performance.
    Class changeIsa(Class newCls);

    bool hasNonpointerIsa();
    bool isTaggedPointer();
    bool isBasicTaggedPointer();
    bool isExtTaggedPointer();
    bool isClass();

    // object may have associated objects?
    bool hasAssociatedObjects();
    void setHasAssociatedObjects();

    // object may be weakly referenced?
    bool isWeaklyReferenced();
    void setWeaklyReferenced_nolock();

    // object may have -.cxx_destruct implementation?
    bool hasCxxDtor();

    // Optimized calls to retain/release methods
    id retain();
    void release();
    id autorelease();

    // Implementations of retain/release methods
    id rootRetain();
    bool rootRelease();
    id rootAutorelease();
    bool rootTryRetain();
    bool rootReleaseShouldDealloc();
    uintptr_t rootRetainCount();

    // Implementation of dealloc methods
    bool rootIsDeallocating();
    void clearDeallocating();
    void rootDealloc();

private:
    void initIsa(Class newCls, bool nonpointer, bool hasCxxDtor);

    // Slow paths for inline control
    id rootAutorelease2();
    bool overrelease_error();

#if SUPPORT_NONPOINTER_ISA
    // Unified retain count manipulation for nonpointer isa
    id rootRetain(bool tryRetain, bool handleOverflow);
    bool rootRelease(bool performDealloc, bool handleUnderflow);
    id rootRetain_overflow(bool tryRetain);
    bool rootRelease_underflow(bool performDealloc);

    void clearDeallocating_slow();

    // Side table retain count overflow for nonpointer isa
    void sidetable_lock();
    void sidetable_unlock();

    void sidetable_moveExtraRC_nolock(size_t extra_rc, bool isDeallocating, bool weaklyReferenced);
    bool sidetable_addExtraRC_nolock(size_t delta_rc);
    size_t sidetable_subExtraRC_nolock(size_t delta_rc);
    size_t sidetable_getExtraRC_nolock();
#endif

    // Side-table-only retain count
    bool sidetable_isDeallocating();
    void sidetable_clearDeallocating();

    bool sidetable_isWeaklyReferenced();
    void sidetable_setWeaklyReferenced_nolock();

    id sidetable_retain();
    id sidetable_retain_slow(SideTable& table);

    uintptr_t sidetable_release(bool performDealloc = true);
    uintptr_t sidetable_release_slow(SideTable& table, bool performDealloc = true);

    bool sidetable_tryRetain();

    uintptr_t sidetable_retainCount();
#if DEBUG
    bool sidetable_present();
#endif
};

从代码中我们知道isa的类型是isa_t, 进入isa_t类型:

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

    Class cls;
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
#endif
};

我们发现isa_t是一个联合体,使用联合体数据共享一片内存,节省消耗.
进入 Class ISA();

#   define ISA_MASK        0x00007ffffffffff8ULL
inline Class 
objc_object::ISA() 
{
    assert(!isTaggedPointer()); 
#if SUPPORT_INDEXED_ISA
    if (isa.nonpointer) {
        uintptr_t slot = isa.indexcls;
        return classForIndex((unsigned)slot);
    }
    return (Class)isa.bits;
#else
    return (Class)(isa.bits & ISA_MASK);
#endif
}

代码中我们发现,isa_t联合体中的 bits & ISA_MASK,能直接得出该对象的isa对象的内存地址,我们用一个实例来验证一下。

   LGPerson *p = [[LGPerson alloc] init];
        p.name      = @"Cooci";
        p.age  
E4760E68820834F90A96606A0B2B542C.png

相关文章

  • 类的结构分析

    isa继续探索 在对象探索-初探isa文章中,简单探索了isa的构成,这篇文章主要将isa之间的关系及类的内存结构...

  • isa探索

    打开objc-750源码,找到结构体objc_object,直接对isa源码分析。 从代码中我们知道isa的类型是...

  • iOS 探索isa

    一、OC对象的本质是什么? 可能有很多同学都知道答案,即对象的本质是结构体。但是怎么证明呢?今天我们就来一起验证下...

  • isa底层探索

    前言 相信有一定iOS开发经验的同学都会知道,对象的本质在底层都是一个结构体,底层代码如下 在之前的文章alloc...

  • ISA指针探索

    1.什么是isa指针呢? 众所众知的每个对象里面都有一个isa指针,而这个isa指针指向哪里呢?首先我们先来看一段...

  • iOS底层探索004-类分析

    iOS底层探索-目录 1. 类的分析 主要分析两个部分:isa的走向和继承关系 isa分析 类的isa走向,参考这...

  • iOS底层-isa结构(isa_t)

    在iOS 底层-- isa指向探究中探索了isa的指向,那么isa的结构具体是什么样的。从源码中来着手研究。 一、...

  • 03 - isa结构探索

    1

  • 对象探索-初探isa

    知识要点: Clang简介对象本质类和对象如何关联(initIsa) Clang Clang是一个C语言、C++、...

  • ios isa的探索

    1. isa在alloc中的实现 在alloc探索[https://www.jianshu.com/p/08079...

网友评论

      本文标题:isa探索

      本文链接:https://www.haomeiwen.com/subject/rokpyqtx.html