OC-底层实现

class和id,NSObject的本质

typedef struct objc_object NSObject;
typedef struct objc_class *Class;
typedef struct objc_object *id;

isa

initIsa()

正常来说是使用传进来的cls来初始化isa 因为在创建的时候每个对象会调用[[A alloc]init] init就会调用alloc alloc会传入self 这个self就是A的对象 就是型参 Class cls 比如
bool dtor = cls->hasCxxDtor() 然后initIsa(cls,dtor)就可以用来初始化isa

objc_object::initIsa(Class cls, bool nonpointer, UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT bool hasCxxDtor)

isa_t

在initIsa中 isa_t newisa(0)
是一个联合体 因为使用联合体+位域 所以只占用一个指针的空间
除了存储指针值还保存了其他信息 比如

nonpointer 占用1bit,标识是否开启isa优化.如果是一个指针值该位为0,则表示当前结构的值只是一个指针没有保存其他信息;如果为1,则表示当前结构不是指针,而是一个包含了其他信息的位域结构
has_assoc 当前对象是否使用objc_setAssociatedObject动态绑定了额外的属性
has_cxx_ctor是否有C++的构造函数
has_cxx_dtor 是否含有C++或者OC的析构函数,不包含析构函数时对象释放速度会更快
shiftcls 这个值相当于早期实现中的isa指针,是真实的指针值,在arm64处理器上只占据33位,可见其实在内存中可以用来存储对象指针的空间是很有限的
magic 用于判断对象是否已经完成了初始化,在arm64中0x16是调试器判断当前对象是真的对象还是没有初始化的空间(在x86_64中该值为0x3b)
weakly_referenced 是否是弱引用对象
deallocating 对象是否正在执行析构函数(是否在释放内存)
has_sidetable_rc 判断是否需要用sidetable去处理引用计数
extra_rc 存储该对象的引用计数值减一后的结果. 当对象的引用计数使用extra_rc足以存储时
unused 对象是否被释放
has_sidetable_rc=0 当对象的引用计数使用extra_rc不能存储时has_sidetable_rc=1.可见对象的引用计数主要存储在两个地方:如果isa中extra_rc足以存储则存储在isa的位域中;如果isa位域不足以存储,就会使用sidetable去存储。
参考网站

内存问题

创建

alloc->_objc_rootAlloc->callAlloc->allocWithZone(和alloc)->_objc_rootAllocWithZone->initInstanceIsa
init只是把对象返回

销毁

release会调用rootRelease
如果newisa.nonpointer = 0 则调用sidetable_release方法
sidetable_release会看是否符合条件

if (do_dealloc  &&  performDealloc) {
        ((void(*)(objc_object *, SEL))objc_msgSend)(this, @selector(dealloc));

会判断sidetable中refcnt是否小于SIDE_TABLE_DEALLOCATING 如果小于则表示这个对象要被释放,则调用dealloc方法。如果不小于则直接执行refcnt -= SIDE_TABLE_RC_ONE;即refcnt-1操作。
如果newisa.nonpointer = 1 则 对newisa.extra_rc进行-1操作,然后判断newisa.extra_rc是否有向下溢出,并执行对应操作。

rootDealloc会调用object_dispose
object_dispose调用free

_object_dispose(id anObject)

会调用

objc_destructInstance(anObject);//会查看一下has_cxx_dtor是否有析构函数 如果有就调用他的析构 再查看是否有关联对象 如果有就取消关联 然后会做一个clearDeallocating不知道干嘛的

然后用freedObjectClass来设置Isa 将isa里面的信息都设置为nil

anObject->initIsa(_objc_getFreedObjectClass ());

最后调用

free(anObject);//调用dealloc

void *objc_destructInstance(id obj)

void *objc_destructInstance(id obj) 
{
    if (obj) {
        Class isa = obj->getIsa();

        if (isa->hasCxxDtor()) {
            object_cxxDestruct(obj);
        }

        if (isa->instancesHaveAssociatedObjects()) {
            _object_remove_assocations(obj);
        }

        objc_clear_deallocating(obj);
    }

    return obj;
}

freedObjectClass

static const void* freedObjectClass[12] =
{
    Nil,				// isa
    Nil,				// superclass
    "FREED(id)",			// name
    0,				// version
    0,				// info
    0,				// instance_size
    nil,				// ivars
    nil,				// methodLists
    (Cache) &_objc_empty_cache,		// cache
    nil,				// protocols
    nil,			// ivar_layout;
    nil			// ext
};

你可能感兴趣的:(OC,ios,objective-c,开发语言)