• alloc & init & dealloc


      在Objective-C中,alloc,init和dealloc是经常使用的函数,那么它们内部到底是如何实现的呢?通过查看libobjc运行时库,可以发现他们的工作原理。

      1 alloc

      alloc的功能就是为对象分配内存,关键代码如下:

    if (!UseGC  &&  !zone  &&  fast) {
            obj = (id)calloc(1, size);
            if (!obj) return nil;
            obj->initInstanceIsa(cls, hasCxxDtor);
        } 

      在上面的代码中,calloc就是用来位对象分配内存的,并且calloc还会将这块内存区域初始化位0,其中的size就是对象的大小=isa指针(下面介绍) + 对象中的实例变量。为了内存对齐,size的大小可能会包含一些填充字节。分配好的内存被转换为id类型,下面是运行时库中对id类型的定义:

    typedef struct objc_object *id;

      可以看到,id类型其实就是一个结构体指针,该结构体为objc_object,而struct objc_object的定义为(只展示了struct里面的实例变量,去掉了struct里面的方法):

    struct objc_object {
    private:
        isa_t isa;
    }

      struct objc_object中的成员变量isa是一个指针,指向的是对象所属类的Class对象。

      分配好内存之后,调用obj->initInstanceIsa方法,这个方法的作用就是用该对象所属类的Class对象地址初始化对象的isa指针,类的Class对象地址由参数cls提供。有关对象,对象所属类的Class对象的介绍,可以参看链接:刨根问底Objective-C Runtime(2)- Object & Class & Meta Class

      

      2 init

      init方法很简单,什么也不做,简单的返回对象地址,源码如下:

    - (id)init {
        return _objc_rootInit(self);
    }
    
    
    id
    _objc_rootInit(id obj)
    {
        // In practice, it will be hard to rely on this function.
        // Many classes do not properly chain -init calls.
        return obj;
    }

      3 dealloc

      dealloc的作用就是释放内存,关键源代码如下:

    id 
    object_dispose(id obj)
    {
        if (!obj) return nil;
    
        objc_destructInstance(obj);
        
    #if SUPPORT_GC
        if (UseGC) {
            auto_zone_retain(gc_zone, obj); // gc free expects rc==1
        }
    #endif
    
        free(obj);
    
        return nil;
    }

      object_dispose是dealloc用来释放内存所调用的函数,可以看到,object_dispose只是简单的调用了free函数来释放内存。但是在调用free之前,object_dispose调用了objc_destructInstance。objc_destructInstance函数如下:

    void *objc_destructInstance(id obj) 
    {
        if (obj) {
            // Read all of the flags at once for performance.
            bool cxx = obj->hasCxxDtor();
            bool assoc = !UseGC && obj->hasAssociatedObjects();
            bool dealloc = !UseGC;
    
            // This order is important.
            if (cxx) object_cxxDestruct(obj);
            if (assoc) _object_remove_assocations(obj);
            if (dealloc) obj->clearDeallocating();
        }
    
        return obj;
    }

    其中标红色的方法会对类中包含的成员变量进行释放,这个释放动作是由编译器来保证的(ARC下),即使overwrite了某个类的dealloc,并且overwrite dealloc时没有对成员变量赋值nil,这个过程也不受影响,照样进行。

    最后附上libObjc的下载连接:https://github.com/longv2go/objc4-646

  • 相关阅读:
    更改开机运行级别
    三个路由的路由表信息
    网络
    网卡配置文件与网络命令显示不一致
    使CentOS7恢复网卡传统命名
    删除CentOS7的虚拟网卡
    将克隆的eth3和eth4改为eth0和eth1
    单臂路由--1个物理网卡绑定多个IP地址
    洛谷P1098 字符串的展开
    洛谷P1086 花生采摘
  • 原文地址:https://www.cnblogs.com/chaoguo1234/p/4770035.html
Copyright © 2020-2023  润新知