美文网首页
iOS的内存管理

iOS的内存管理

作者: 平凡码农 | 来源:发表于2019-03-13 12:08 被阅读0次

    在ARM64操作系统下,一个指针占用64bit,但其实存储一个对象的地址32就够了。而且访问堆内存的效率比访问栈要慢。所以基于性能和内存使用效率,苹果推出了新的内存管理的功能。

    我们知道,对象的定义为:

    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();
    

    其中,将isa指针定义为private私有变量。是为了不让外部直接访问。

    为什么不让访问呢?因为isa已经不再是一个堆内存对象的地址,而是一个union结构。

    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
    };
    

    union的意思就是,可能是Class cls,也可能是uintptr_t bits,也可能是

    struct {
    uintptr_t nonpointer        : 1;                                       \
          uintptr_t has_assoc         : 1;                                       \
          uintptr_t has_cxx_dtor      : 1;                                       \
          uintptr_t shiftcls          : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \
          uintptr_t magic             : 6;                                       \
          uintptr_t weakly_referenced : 1;                                       \
          uintptr_t deallocating      : 1;                                       \
          uintptr_t has_sidetable_rc  : 1;                                       \
          uintptr_t extra_rc          : 19
    }
    

    那到底是什么呢?我们来看下获取isa的方法的实现。

    inline Class objc_object::getIsa() 
    {
        if (!isTaggedPointer()) return ISA();
    
        uintptr_t ptr = (uintptr_t)this;
        if (isExtTaggedPointer()) {
            uintptr_t slot = 
                (ptr >> _OBJC_TAG_EXT_SLOT_SHIFT) & _OBJC_TAG_EXT_SLOT_MASK;
            return objc_tag_ext_classes[slot];
        } else {
            uintptr_t slot = 
                (ptr >> _OBJC_TAG_SLOT_SHIFT) & _OBJC_TAG_SLOT_MASK;
            return objc_tag_classes[slot];
        }
    }
    

    可以看出,不是TaggedPoint时,使用的是ISA。当是TaggedPoint并且为ExtTaggedPointer,则按位操作,返回3~37字节的真实的对象的地址。当就是TaggedPoint且不为ExtTaggedPointer时,返回objc_tag_classes数组中的位置。

    相关文章

      网友评论

          本文标题:iOS的内存管理

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