ios中的初始化函数

作者:代培
地址:http://blog.csdn.net/dp948080952/article/details/52337229
转载请注明出处
在iOS中最标准的初始化方法是alloc+init,而此外也可以使用new来初始化,当然这些初始化方法都是我们用来创建一个实例时使用的,你可能不知道当类在初始化时所使用的load和initialize方法。

alloc

大家都知道alloc是分配内存,但其实alloc函数并不是仅仅做了分配内存的工作,总共做了一下三件事情

  • 为新的实例对象分配内存
  • 初始化isa指针,使其指向类的对象(苹果的文档中是这样描述的:a data structure that describes the class,这应该是类的对象的意思)
  • 将所有的实例变量的内存设为0

    官方建议,不要重写alloc方法使其进行一些初始化操作,应该将其放在init方法中。
    由于历史原因,alloc调用allocWithZone:方法,所以我看有的地方说用alloc和init的方法实例化要好于用new方法,因为alloc使用了zone在分配内存时会选用相邻的内存,减少调用时的消耗,提升程序的速度,后来在OC高级编程这本书中看到,NSZone是为了防止内存碎片化而引入的结构,而现在的运行时系统简单的忽略了区域的概念,因为运行时系统中的内存管理本身已极具效率了,使用区域管理内存反而会引起内存使用效率低下以及源代码复杂化等问题。

init

init方法用于实例的初始化工作,但是在init方法中需要首先调用父类的此方法,然后在进行自身的初始化

从苹果盗的图

以下是对苹果文档的翻译

  • 首先调用superclass的init方法
  • 检查superclass返回的对象是否为nil,如果返回值为nil处理错误并返回nil
  • 返回对象不为nil初始化对象的实例变量
  • 返回初始化好的实例变量,或者是nil

这是我平时写代码时最常用的重写初始化的方法

- (id)init {
    self = [super init];
    if (self) { 
        //do some initial job
    }
    return self;
}

alloc init retain release dealloc 的区别

  • alloc是创建变量
  • init是初始化变量
  • dealloc是释放变量
  • retain是引用计数加1
  • release是引用计数减1

alloc、new、copy、mutableCopy 等开头的方法创建对象时都会发送一条retain消息,使引用计数加1,获得该对象的所有权,当不再使用该对象时,需要发送release消息,使其引用计数减1,在不适合立即回收对象时,应当优先使用autorelease。
但是在ARC时代,这些都不需要程序员去考虑(心疼MRC时代的程序员两秒),编译器会在适当的地方插入,但是我觉得这些也不能不知道。

new

This method is a combination of alloc and init. Like alloc, it
initializes the isa instance variable of the new object so it points
to the class data structure. It then invokes the init method to
complete the initialization process.

根据苹果的官方文档,new = alloc + init

  • new是否是OC的关键字

看到一本书中说OC没有new这个关键字,让我产生了一些疑问,我在写代码的时候是用过new方法的,而书中又说new可以看作是一个函数,是alloc+init,但是new到底是不是oc关键字呢?
我Google了一下,关于这个问题的讨论很少,所以我就打开我的Xcode看了下

我的关键字的字体颜色是深红色(就是Xcode默认的配色)

而查看了NSObject中init alloc new的声明,真的很出乎我的意料,new是关键字,init alloc却不是关键字,而是函数。
我查了一下百度百科对关键字的定义:

关键字是用来标识文件中各个记录的特定数据项目的值,是电脑语言里事先定义的,有特别意义的标识符,有时又叫保留字。

所以是否把new归为关键字,苹果肯定有他的用意,其实只要知道底层new是对alloc和init的封装就可以了,不必纠结这个关键字的问题。

+load函数

Invoked whenever a class or category is added to the Objective-C runtime; implement this method to perform class-specific behavior upon loading.

简单的来看,这个函数就是当类和分类添加到运行时中时会调用的方法,我觉得这个函数可以类似于实例化时的alloc函数,+load函数调用顺序是父类先于子类,主类先于分类。
+load方法是不需要显示的调用的,他是在运行时中被调用的,而且这个方法被调用的非常早,所有loadable的class的load方法都是会被调用的,而如何去确定是否是loadable,只要实现了load函数,就会被加入到loadable_list,我测试了一下,只要你在工程里声明并实现了一个类,同时实现了这个类的load方法,并且编译了这个文件,那么load方法就一定会被调用,而且load方法的调用是先于整个工程的main函数的,也就是说这个应用还没开始运行时,用load对类进行部署工作。
当然我们无法得知在每个类中load函数到底做了什么,但是在load函数中我们却是可以做一些事情比如方法混淆:Method Swizzing

+initialize函数

Initializes the class before it receives its first message.

从苹果官方文档来看,当一个类第一次收到消息时会调用这个函数,也就是说如果没有调用这个类的方法,这个类是不会调用initialize函数的。
在运行时的代码中,initialize被调用的地方只有3处,其中一处就是在lookUpImpOrForward方法中,当在Cache中为发现IMP时继续在寻找时首先会检查这个类是否被initialize,如果没有的化则会调用initialize函数,所以这也符合文档中所说的第一次接收消息时才会被调用。
如果你希望在一个类的方法在被调用前做一些事情,就可以在这个方法中进行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值