iOS 收藏篇

alloc init和new的区别

2020-08-20  本文已影响0人  一个半吊子工程师

本篇文章采用的源码是objc4-781版本

创建对象的两种方式:
UIView *myView = [[UIView alloc] init];
UIView *myView = [UIView new];

在Source/NSObject.mm文件中可以找到alloc方法和new方法的实现
+ (id)new {
    return [callAlloc(self, false/*checkNil*/) init];
}
alloc init

通过new方法创建的实例会调用init方法,那么[Class alloc] init][Class new]这两种方法的唯一区别就在于分配内存这一步,我们可以先找到_objc_rootAlloc的实现函数

_objc_rootAlloc

上图中callAlloc这个函数也是new方法里面调用的函数。

区别:
new 方法调用的时候只传了2个参数,
_objc_rootAlloc 这里传了3个参

下面是callAlloc的源码

callAlloc
从上面的源码来看allocnew进来这个函数的差别什么呢?

就是allocWithZone参数了,从alloc那里的时候为true
new进来的时候为默认值false
从整个callAlloc用到allocWihZone参数的地方就在于最后几行。

// No shortcuts available.
    if (allocWithZone) {
        return ((id(*)(id, SEL, struct _NSZone *))objc_msgSend)(cls, @selector(allocWithZone:), nil);
    }

如果allocWithZone为真则会走[cls allocWithZone:nil],反之则走[cls alloc]

[Class new]就相当于调用[[Class alloc] init],一个为隐式调用,一个为显示调用而已。可以理解为 new为一个快捷键

区别

1.alloc在分配内存的时候使用了zone, 它是在给对象分配内存的时候把关联的对象分配到一个相邻的区域内, 以便于调用时消耗很少的内存, 提升程序的处理速度;

2.使用new来创建对象的话, 初始化方法被固定死了, 只能使用init, 不能调用其他的initWith方法;

3.使用alloc init方法, 我们可以重写init方法, 但是如果使用new来创建的话就只能走系统的init方法了.

上一篇下一篇

猜你喜欢

热点阅读