new 与 alloc 还有 free

   className* object = [className new];

  or

    className* object = [[className alloc] init];

背景说明,new是较为老式的写法,后来发现只有一个new不好使,才引入了alloc和init这种写法,保留new一是向后兼容,二是很多时候是一种更简单的写法。其实是一样的,new在内部调用的alloc和init.

源代码:

+ new

{

id newObject = (*_alloc)((Class)self, 0);

Class metaClass = self->isa;

if (class_getVersion(metaClass) > 1)

        return [newObject init];

else

    return newObject;

}



+ alloc

{

return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); 

}

- init

{

    return self;

}

[className new]基本等同于[[className alloc] init]. 区别只在于alloc分配内存的时候使用了zone,这个zone是个什么东东呢?它是给对象分配内存的时候,把关联的对象分配到一个相邻的内存区域内,以便于调用时消耗很少的代价,提升了程序处理速度.

什么要把alloc 和init 分开?

1. 可以使用多种init方法

2. 显示调用总比隐式调用要好”

如果确实不需要用其他的init函数,比如initWithString, 只是使用 [Nsobject alloc] init] ,那用new的方法更加方便

 * new doesn't support custom initializers (like initWithString)

 * alloc-init is more explicit than new


深挖:  (*_zoneAlloc)  与  (*_alloc)

id (*_zoneAlloc)(Class, size_t, void *) = _class_createInstanceFromZone;

PRIVATE_EXTERN id

_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone)

{

    id obj;

    size_t size;

    // Can't create something for nothing

    if (!cls) return nil;

    // Allocate and initialize

    size = _class_getInstanceSize(cls) + extraBytes;

    // CF requires all objects be at least 16 bytes.

    if (size < 16) size = 16;

#if SUPPORT_GC

    if (UseGC) {

        obj = (id)auto_zone_allocate_object(gc_zone, size,

                                            AUTO_OBJECT_SCANNED, 0, 1);

    } else

#endif

    if (zone) {

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

    } else {

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

    }

    if (!obj) return nil;

    obj->isa = cls;

    if (_class_hasCxxStructors(cls)) {

        obj = _objc_constructOrFree(cls, obj);

    }

    return obj;

}

上面那段代码的作用是:

1、得到这个类占用多少空间,最小占16 bytes

2、然后就给这个实例分配多少空间, 如果失败的话就返回nil

3、把这个实例的isa设置成这个类对象

4、如果cls的info设置了get属性就用cls这个类在obj这个空间去构造一个实例,跟进去是


id (*_alloc)(Class, size_t) = _class_createInstance;

static id _class_createInstance(Class cls, size_t extraBytes)

{

    return _class_createInstanceFromZone (cls, extraBytes, NULL);

}

free

- free

{

    return (*_dealloc)(self);

}

+ free

{

    return nil;

}


_object_dispose

static id  _object_dispose(id anObject)

{

    if (anObject==nil) return nil;

    objc_destructInstance(anObject);

#if SUPPORT_GC

    if (UseGC) {

        auto_zone_retain(gc_zone, anObject); // gc free expects rc==1

    } else

#endif

    {

        // only clobber isa for non-gc

        anObject->isa = _objc_getFreedObjectClass ();

    }

    free(anObject);

    return nil;

}

objc_destructInstance

void *objc_destructInstance(id obj)

{

    if (obj) {

        Class isa = _object_getClass(obj);

        if (_class_hasCxxStructors(isa)) {

               object_cxxDestruct(obj);

        }

        if (_class_instancesHaveAssociatedObjects(isa)) {

            _object_remove_assocations(obj);

        }

        if (!UseGC) objc_clear_deallocating(obj);

    }

    return obj;

}


执行一个叫object_cxxDestruct的东西干了点什么事(沿着继承链逐层向上搜寻SEL_cxx_destruct这个selector, 找到函数实现(void (*)(id)(函数指针)并执行)

执行_object_remove_assocations去除和这个对象关联的对象

执行objc_clear_deallocating,清空引用计数表并清除弱引用表,将所有weak引用指nil

---------------------


参考:https://blog.csdn.net/uxyheaven/article/details/38120335

https://blog.csdn.net/lixin8201/article/details/50407955

https://blog.csdn.net/u013375242/article/details/49512183

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,774评论 0 9
  • 终于把前面的base文件夹简简单单的看了一遍,终于可以回到正片上来了,保证不烂尾。 项目天天用yymodel解析数...
    充满活力的早晨阅读 1,393评论 1 0
  • 我们常常会听说 Objective-C 是一门动态语言,那么这个「动态」表现在哪呢?我想最主要的表现就是 Obje...
    Ethan_Struggle阅读 2,231评论 0 7
  • Objective-C语言是一门动态语言,他将很多静态语言在编译和链接时期做的事情放到了运行时来处理。这种动态语言...
    tigger丨阅读 1,431评论 0 8
  • 6月28日 此刻身体感受:眼困 此刻情绪感受:平静 标题:今天的丰盛 1,今天一早依旧五点起床,用两个小时的时间泛...
    汪圆圆阅读 239评论 0 0