美文网首页
第九更 生命周期

第九更 生命周期

作者: RunningTeemo | 来源:发表于2018-05-03 10:54 被阅读0次

一、程序的生命周期


屏幕快照 2018-05-02 下午8.03.24.png

分析:

1.application:didFinishLaunchingWithOptions:
程序首次已经完成启动时执行,一般在这个函数里创建window对象,将程序内容通过window呈现给用户。

applicationWillResignActive(非活动)
程序将要失去Active状态时调用,比如有电话进来或者按下Home键,之后程序进入后台状态,对应的applicationWillEnterForeground(即将进入前台)方法。
该函数里面主要执行操作:
a . 暂停正在执行的任务
b. 禁止计时器
c. 减少OpenGL ES帧率
d. 若为游戏应暂停游戏

3.applicationDidEnterBackground(已经进入后台)
对应applicationDidBecomeActive(已经变成前台)

该方法用来:
a. 释放共享资源
b. 保存用户数据(写到硬盘)
c. 作废计时器
d. 保存足够的程序状态以便下次修复;

applicationWillEnterForeground(即将进入前台)
程序即将进入前台时调用,对应applicationWillResignActive(即将进入后台),
这个方法用来: 撤销applicationWillResignActive中做的改变。

applicationDidBecomeActive(已经进入前台)
程序已经变为Active(前台)时调用。对应applicationDidEnterBackground(已经进入后台)。
注意: 若程序之前在后台,在此方法内刷新用户界面

applicationWillTerminate
程序即将退出时调用。记得保存数据,如applicationDidEnterBackground方法一样。

二,UIViewController的生命周期


1354776680_2123-2.png
// 如果连接了串联图storyBoard 走这个方法
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
     NSLog(@"%s", __FUNCTION__);
    if (self = [super initWithCoder:aDecoder]) {
        
    }
    return self;
}

// xib 加载 完成
- (void)awakeFromNib {
    [super awakeFromNib];
     NSLog(@"%s", __FUNCTION__);
}

// 加载视图(默认从nib)
- (void)loadView {
    NSLog(@"%s", __FUNCTION__);
    self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.view.backgroundColor = [UIColor redColor];
}

//视图控制器中的视图加载完成,viewController自带的view加载完成
- (void)viewDidLoad {
    NSLog(@"%s", __FUNCTION__);
    [super viewDidLoad];
}


//视图将要出现
- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"%s", __FUNCTION__);
    [super viewWillAppear:animated];
}

// view 即将布局其 Subviews
- (void)viewWillLayoutSubviews {
    NSLog(@"%s", __FUNCTION__);
    [super viewWillLayoutSubviews];
}

// view 已经布局其 Subviews
- (void)viewDidLayoutSubviews {
    NSLog(@"%s", __FUNCTION__);
    [super viewDidLayoutSubviews];
}

//视图已经出现
- (void)viewDidAppear:(BOOL)animated {
    NSLog(@"%s", __FUNCTION__);
    [super viewDidAppear:animated];
}

//视图将要消失
- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"%s", __FUNCTION__);
    [super viewWillDisappear:animated];
}

//视图已经消失
- (void)viewDidDisappear:(BOOL)animated {
    NSLog(@"%s", __FUNCTION__);
    [super viewDidDisappear:animated];
}

//出现内存警告  //模拟内存警告:点击模拟器->hardware-> Simulate Memory Warning
- (void)didReceiveMemoryWarning {
    NSLog(@"%s", __FUNCTION__);
    [super didReceiveMemoryWarning];
}

// 视图被销毁
- (void)dealloc {
    NSLog(@"%s", __FUNCTION__);
}

三、OC中load方法和initialize方法的异同
对于OC中的类来说,在runtime中会有两个方法被调用:

  • +load
  • +initialize

这两个方法看起来都是在类初始的时候调用的,但其实还是有一些异同,从而可以用来做一些行为。

+load

首先,load方法是一定会在runtime中被调用的,只要类被添加到runtime中了,就会调用load方法,所以我们可以自己实现laod方法来在这个时候执行一些行为。

而且有意思的一点是,load方法不会覆盖。也就是说,如果子类实现了load方法,那么会先调用父类的load方法,然后又去执行子类的load方法。同样的,如果分类实现了load方法,也会先执行主类的load方法,然后又会去执行分类的load方法。所以父类的load会执行很多次,这一点需要注意。而且执行顺序是 类 -> 子类 ->分类。而不同类之间的顺序不一定。

+initialize

与load不同的是,initialize方法不一定会执行。只有当一个类第一次被发送消息的时候会执行,注意是第一次。什么叫发送消息呢,就是执行类的一些方法的时候。也就是说这个方法是懒加载,没有用到这个类就不会调用,可以节省系统资源。

还有一点截然相反,却更符合我们预期的就是,initialize方法会覆盖。也就是说如果子类实现了initialize方法,就不会执行父类的了,直接执行子类本身的。如果分类实现了initialize方法,也不会再执行主类的。所以initialize方法的执行覆盖顺序是 分类 -> 子类 ->类。且只会有一个initialize方法被执行。

Q1:load 方法是如何被调用的?

A1:当 Objective-C 运行时初始化的时候,会通过 dyld_register_image_state_change_handler 在每次有新的镜像加入运行时的时候,进行回调。执行 load_images 将所有包含 load 方法的文件加入列表 loadable_classes ,然后从这个列表中找到对应的 load 方法的实现,调用 load 方法。

load 可以说我们在日常开发中可以接触到的调用时间最靠前的方法,在主函数运行之前,load 方法就会调用。

由于它的调用不是惰性的,且其只会在程序调用期间调用一次,最最重要的是,如果在类与分类中都实现了 load 方法,它们都会被调用,不像其它的在分类中实现的方法会被覆盖,这就使 load 方法成为了方法调剂的绝佳时机。

但是由于 load 方法的运行时间过早,所以这里可能不是一个理想的环境,因为某些类可能需要在在其它类之前加载,但是这是我们无法保证的。不过在这个时间点,所有的 framework 都已经加载到了运行时中,所以调用 framework 中的方法都是安全的。
用途:1:可以新建类在该类中实现一些配置信息 2:runtime交换方法的时候,因为只需要交换一次方法,所有可以在该方法中实现交换方法的代码,用于只实现一次的代码 2:+ (void)initialize:当类被初始化的时候调用,可能会被调用多次,若是没有子类,则只会调用一次,若是有子类的话,该方法会被调用多次,若是子类的继承关系,先会调用父类的+ (void)initialize方法,然后再去调用子类的+ (void)initialize方法(若是继承关系,调用某个方法的时候,先会去父类中查找,若是父类中没有方法的实现就去子类中查找) 用途:1:在设置导航栏的全局背景的时候,只需要设置一次,可以重写该方法设置,最好是在该方法判断子类,若是自己,则实现设置全局导航栏的方法,若不是自己则跳过实现。2:在创建数据库代码的时候,可以在该方法中去创建,保证只初始化一次数据库实例,也可以用dispatch或是懒加载的方法中初始化数据库实例,也能保证只初始化一次数据库实例。其中也可以在+ (void)initialize方法中用dispatch也能保证即使有子类也只会初始化一次

相关文章

  • 第九更 生命周期

    一、程序的生命周期 分析: 1.application:didFinishLaunchingWithOptions...

  • 安卓常用生命周期图

    Activity生命周期 Fragment生命周期 Activity与Fragment 生命周期 GitHub上更...

  • Flutter生命周期

    StatefulWidget的生命周期 StatelessWidget的生命周期 同StatefulWidget更...

  • 分享一些有趣的网络神回复,笑的咪咪痛。。。

    第九更了!!!

  • 进阶react.js

    组件生命周期 组件的生命周期有助于理解组件的运行方式,完成更复杂的组件功能、分析组件错误原因等组件的生命周期: 组...

  • LifeCycle

    简介 生命周期感知型组件:可以相应另一个组件(Activity or Fragment)的生命周期变化。以便代码更...

  • 用户运营(下篇) 如果注定失去,那就尽可能延长

    做运营,我们常会听到用户生命周期的概念。 传统营销学上讲的客户生命周期管理。对互联网运营来说,我更倾向于生命周期的...

  • React 生命周期详解

    React 生命周期详解 生命周期的三个阶段 装载过程: Mouth React组件的第一次渲染DOM的过程, 更...

  • 第九更

    当你被人铭记并口头称赞后,你便获得了名,随之而来的是那无穷无尽的“麻烦”——听说你在某方面很出色,可以帮个忙吗?;...

  • “一定要努力,但是别着急~”

    今天是参加无戒老师“21天写作训练营”的第九天。是训练营开课以来日更的第九天,我个人连续日更的第15天。选择第九天...

网友评论

      本文标题:第九更 生命周期

      本文链接:https://www.haomeiwen.com/subject/alocrftx.html