Objective-C runtime之load和initialize

本文深入探讨了Objective-C中+load和+initialize方法的区别与应用场景。+load方法在类加载时调用,适用于早期初始化;+initialize则在类首次接收消息时调用,更适合于安全的初始化环境。

概述

在C语言中,main()是程序最早开始启动和初始化的地方。 在Objective-C中,application,documents,user interface都有自己初始化的地方,所以,在main()中只是简单的调用 NSApplicationMain。

Objective-C中第一个初始化的地方是 +(void)load. 任何class都能有一个+(void)load。

+load

+load方法在类被加载到系统时调用,这发生在一个很早的时刻, +load的方法的调用顺序为:

  • 链接到的框架初始化(包括+load)
  • 当前镜像(image)的+load
  • 当前镜像的C++静态初始化和C/C++ attribute(constructor)构造函数
  • 链接到你的框架初始化。

下面可以看到load被加载的时机:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-irJPB3vj-1578564738357)(http://static.yhawaii.net/images/iosnotes/startupMain.png)]

+load方法调用的时候尚未有自动释放池,所以如果+load中的内容使用到了自动释放池,则代码需要用@autoreleasepool{}包含。 另外,对应Category中的+load方法并不会覆盖类自身中的+load方法,两个+load方法都会调用,而且Category的+load方法在类自身的+load方法之后调用。
代码例子:

@interface LoadClass : NSObject
@end
@implementation LoadClass


+ (void)load
{
    NSLog(@"####loading");
}


__attribute__((constructor)) static void ConstructorLoad(void)
{
    NSLog(@"ConstructorLoad ");
}

@end


@implementation LoadClass (LoadClass_category)

+ (void)load
{
    NSLog(@"####LoadClass_category loading ");
}

@end


int main(int argc, char *argv[])
{
    @autoreleasepool {

        @autoreleasepool {
            NSLog(@"main Start");
        }
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegateclass]));
    }
}

输出

#### loading
#### LoadClass_category loading
ConstructorLoad
main Start

+initialize

+initialize方法在一个比较安全的环境中调用,比+load更加适合放入初始化代码。

+initialize方法在类首次收到消息时调用,若此类一直没有使用,则+initialize就不会调用。 与+load方法类似的,在向子类发送initialize消息前,总是会先向父类发送initialize消息,如果父类尚未调用+initialize方法则调用
Category中的+initialize方法会覆盖类本身的+initialize方法。如果父类中实现了+initialize方法,而子类中没有重写此方法,则子类初始化时就会使用父类的方法。
代码:


@interface AbstractBase : NSObject
@end

@implementation AbstractBase

+ (void)initialize
{
    NSLog(@"%@ initialize in ",self);
}
@end

@interface SubClasss : AbstractBase
@end

@implementation SubClasss
+ (void)initialize
{
    NSLog(@"%@ initialize in ",self);
}
@end

int main()
{
    @autoreleasepool {
        NSLog(@"main Start");
        [SubClasss class];
        NSLog(@"main End");
    }
    return0;
}

其输出为:

main Start
AbstractBase initialize
SubClasss initialize
main End

如果不想子类使用父类的+initialize方法,则父类的+initialize方法可以这样写。经测试该做法无效

+ (void)initialize
{
   if(self == [ParentClass class])
   {
     ... init..
   }
}

参考资料

所谓IDC,即互联网数据中心,是指在互联网上提供的各项增值服务,具体包括申请域名、租用虚拟主机空间、主机托管等业务。IDC数据中心是一个实现信息的集中处理、存储、传输、交换管理的物理场所,包含机房基础设施、IT基础设施、业务系统数据等内容。机房基础设施包含供电、制冷、机柜、消防、监控等系统,保证IT设备的安全可靠运行;IT基础设备包括服务器、存储、网络等设备,是业务系统运行及数据存储的基础;业务系统运行于IT设备之上,数据存储于IT设备之中,业务系统及数据对最终用户提供服务。随着“互联网+”战略机会点的到来,尤其是云计算已经成为“互联网+”战略的重要支撑,国内三大运营商移动、联通、电信都纷纷加强数据中心的建设。数据显示,中国电信在IDC领域处于领导地位,超过330个数据中心,占全国50%以上的份额。其中2015年的IDC承载专网配套波分网络建设工程的新建部分,就包含了北京、上海、广州、武汉、西安、成都、杭州、南京共8个城市的本地延伸系统;与此同时,中国联通呼浩特云数据中心也在加紧建设;中国移动已建立广州南方云基地、呼浩特云计算中心等基地。据赛迪顾问发布的《中国数据中心布局特点与发展策略研究》指出,IDC行业进入了产业升级的关键时期,正由资源消耗型向应用服务型升级转型,数据中心整合升级加速,运营商与IDC服务商加快数据中心全国布局,数据中心进入新一轮投资高峰期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值