[翻译]Obejective-C的类加载与初始化
来源:互联网 发布:java 嵌入式开发哪个好 编辑:程序博客网 时间:2024/04/28 17:36
作为一个iOS程序员,你一般情况下并不需要关心类是如何加载到内存里的。这是一个复杂的过程,由运行时处理的,并早于你的代码运行。
对于大部分的类,你只需要知道如何使用即可,但是有些时候,你要做一些特殊的处理,比如一个某个类想创建一个全局的表,用来加载本地的用户数据或则其他一些任务。
Objective-C运行时采用两种方式来实现这个需求:+initialize和+load。
+load
如果你在类里实现了这个方法,只要这个类一旦加载,就会触发+load方法。如果你在程序中或程序链接的动态库中实现了该方法,此方法会在main()调用前加载,如果你在可执行的包里实现了load方法,便会在此包加载时执行。
因为load方法执行在程序的早期,因此你必须非常小心。很显然,类的加载有先后,必然有些类早于另外一些类,所以在你在某个类的load方法写代码时,你不能保证其他类已经加载并可以调用。更严重的情况是,你app(框架或插件)中的某些C++的静态初始化器,也许并未开始运行,所以如果你的代码有赖于此,可能会引发崩溃。有一个好的情况是,你链接的框架(.framework)肯定会早于你的类加载,因此你可以放心使用框架里的类。父类也会早于子类被加载,因此你也可以放心的使用父类。有一点需要注意,因为load方法执行时,自动释放池并未创建,因此如果你有用到内存相关的方法,请自己手动创建一个内存管理池。
load方法的一个有趣的功能是,如果你在类别里实现了load方法,在类里也同样实现,他们都会被执行。这和你所知的类别可能有点出入,但是因为load比较特别。这就意味着,你可以在load方法里做一些特别的事情,比如方法交换。
+initialize
initialize方法执行在一个比较稳定的环境,也是比load方法更适合加代码的地方。initialize有趣的地方在于它是懒加载的,甚至永不加载,当一个类加载时候,它不会执行。当给类发送一个消息的时候,这个类就会检测是否已经初始化过了,如果没有,就进行初始化。你可以认为它执行的代码大概如下:
id objc_msgSend(id self, SEL _cmd, ...) { if(!self->class->initialized) [self->class initialize]; ...send the message... }
当然,实际上肯定比上面的代码复杂,因为涉及到线程安全及其他。因此我们可以知道,一个类的initialize方法只会执行一次,并且会在此类收到第一个消息的时候执行。和load一样,initialize消息会在本类处理前,会先将消息发送给它所有的父类(译者注:load是实现了就会执行,initialize是发送了消息肯定会执行,如果本身没实现,就会执行继承于父类的方法),之后再自己处理消息。
使用initialize会比load更安全,因为不需要太考虑时间点。而且肯定是在UIApplicationmain()之后。
由于initialize的懒运行,因此不适合在里面注册类,
这个特性,让你可以使用initialize更任性,而且你可以不用担心在类加载时候浪费资源。
在使用initialize的时候,你需要注意一点,在我们上面嵌入的代码中,有执行[self->class initialize],这意味着,如果你的类未实现此方法,就会调用继承自父类的initialize方法。正因如此,你最好在代码中加入判断:
+ (void)initialize { if(self == [WhateverClass class]) { ...perform initialization... } }
如果你不加入判断,如果有一个子类继承于它,你写的initialize方法可能会执行多次,即时子类没有实现自身的initialize方法。就算你没有子类,但是当你此类使用到苹果的kvo/kvc机制,也会帮你生成一个子类。
原文: http://math.stackexchange.com/
- [翻译]Obejective-C的类加载与初始化
- Obejective-C基础知识
- Obejective-c学习1
- Obejective-C语法
- 类的加载与初始化
- 类的加载与初始化
- JAVA类的加载与初始化
- Java类的加载与初始化
- 关于java类的加载与初始化
- 类的加载、连接与初始化
- Java类的加载与初始化
- Java 类加载与初始化
- 类加载与初始化顺序
- Java 类加载与初始化
- Java 类加载与初始化
- Java 类加载与初始化
- Java类加载与初始化
- Java 类加载与初始化
- 含有HeaderView和FooterView的RecyclerViewAdapter
- 以正确的方式开源 Python 项目
- 1065. A+B and C (64bit) (20)
- linux中用户相关的命令
- 黑白图像
- [翻译]Obejective-C的类加载与初始化
- 路由消息填充
- 黑马程序员——Java基础——IO流(一)
- Yii自定义错误页面(403,404)和NGINX 配置404错误页面转向
- Android帧动画三步骤
- Lua:访问模块、创建模块、子模块与包
- 文本编辑器
- gradle工程导入eclipse---下载安装CAS证书
- 自定义属性