iOS类方法load、initialize

2021-10-29  本文已影响0人  孤独_行者
导语.png

导语:iOS开发中经常会看到在自定义类中重写load、initialize两个类方法,之前对这两个方法理解比较浅,今天来深入探讨下两个方法的实际作用

load方法

  1. 程序启动的时候,会将所有类加载到代码区。
  2. load方法会在当前类被加到内存的时候调用,整个过程只会调用一次。
  3. 如果类存在继承关系,则会先调用父类的load方法,然后调用子类的load方法。
  4. 如果类的分类也实现了load方法,会先调用类的load方法,而后调用分类的load方法
  5. 当子类没有实现load方法,不会调用父类的loaf方法
2021-10-29 09:13:42.465207+0800 类的本质[2693:59888] +[Person load]
2021-10-29 09:13:42.466004+0800 类的本质[2693:59888] +[Man load]
2021-10-29 09:13:42.466063+0800 类的本质[2693:59888] +[GentleMan load]
2021-10-29 09:13:42.466197+0800 类的本质[2693:59888] +[Person(Work) load]
2021-10-29 09:13:42.466235+0800 类的本质[2693:59888] +[Man(Work) load]
2021-10-29 09:13:42.466269+0800 类的本质[2693:59888] +[GentleMan(Work) load]

上面的类的继承关系Person > Man > GentleMan,所以依次调用Person、Man、GentleMan的load方法,分类的load方法会在类的load方法调用完之后调用,调用的顺序由编译的顺序决定。

Person.png
2021-10-29 09:13:42.466197+0800 类的本质[2693:59888] +[Person(Work) load]
2021-10-29 09:13:42.466235+0800 类的本质[2693:59888] +[Man(Work) load]
2021-10-29 09:13:42.466269+0800 类的本质[2693:59888] +[GentleMan(Work) load]
GentleMan.png
2021-10-29 09:21:59.535424+0800 类的本质[2929:67061] +[GentleMan(Work) load]
2021-10-29 09:21:59.535470+0800 类的本质[2929:67061] +[Person(Work) load]
2021-10-29 09:21:59.535510+0800 类的本质[2929:67061] +[Man(Work) load]

initialize方法

  1. initialize方法会在类第一次使用的时候调用。
  2. initialize方法是阻塞安全的,所以initialize方法中应该做一些简单的初始化操作
  3. 如果子类也实现了initialize方法,会跟load方法调用的顺序一样,先调用父类的initialize方法,之后调用子类的initialize方法
  4. 如果子类没有实现initialize,会调用父类的initialize方法(所以父类的initialize有可能调用多次,可以理解为子类没有实现initialize方法时,会拷贝一份父类的initialize方法,而后在依次调用)
  5. 如果分类重写了initialize方法,会覆盖类本身的initialize方法
  6. 由于是系统自动调用,也不需要再调用 [super initialize],否则父类的initialize会被多次执行。子类会从继承关系依次调用
  7. 当有多个Category都实现了initialize方法,会覆盖类中的方法,只执行一个(会执行Compile Sources 列表中最后一个Category 的initialize方法)
2021-10-29 09:38:40.921775+0800 类的本质[3416:81482] +[Person initialize]
2021-10-29 09:38:40.922198+0800 类的本质[3416:81482] +[Man initialize]
2021-10-29 09:38:40.922246+0800 类的本质[3416:81482] +[GentleMan initialize]

GentleMan没有实现initialize方法的时候

2021-10-29 09:40:18.681950+0800 类的本质[3463:82974] +[Person initialize]
2021-10-29 09:40:18.682322+0800 类的本质[3463:82974] +[Man initialize]
2021-10-29 09:40:18.682369+0800 类的本质[3463:82974] +[Man initialize]

Person分类实现了initialize方法

2021-10-29 09:41:14.920573+0800 类的本质[3491:83855] +[Person(Work) initialize]
2021-10-29 09:41:14.920945+0800 类的本质[3491:83855] +[Man initialize]
2021-10-29 09:41:14.920999+0800 类的本质[3491:83855] +[Man initialize]

总结

1、initialize只会调用一次,分类会覆盖本身的initialize方法,所以如果需要类和分类分别独立初始化,使用load方法更好

2、initialize方法中不应该执行太复杂的初始化过程,而应将其限制为简单的类本地初始化

3、当子类没有实现initialize方法时候,防止父类的initialize方法多次调用

4、官方解释

官方.png
//In Person.m
+(void)initialize
{
    if(self == [Person class])
    {
          NSLog(@"%s",__FUNCTION__);
    }
}
上一篇下一篇

猜你喜欢

热点阅读