Skip to content

Latest commit

 

History

History
121 lines (70 loc) · 5.49 KB

File metadata and controls

121 lines (70 loc) · 5.49 KB

iOS

一、 load和initialize区别以及它们有哪些应用?

load

+ load 方法在文件被装载时调用,调用在 main 函数之前。
调用方式: 会循环调用所有类的 + load 方法。这里直接使用函数内存地址的方式 (*load_method)(cls, SEL_load); 对 +load 方法进行调用的。而非使用 objc_msgSend 的方式。
这样调用的方式使得,父类、子类和分类中的 +load 是不同的。也就是说子类没有实现 +load方法,那么当他加载时 runtime 是不会去调用父类的 +load 方法。同理,当一个类和它的分类都实现了 +load 方法时,两个方法都会被调用。

要点:

  • 调用时机比较早,运行环境有不确定因素。具体说来,在iOS上通常就是App启动时进行加载,但当load调用的时候,并不能保证所有类都加载完成且可用,必要时还要自己负责做auto release处理。对于有依赖关系的两个库中,被依赖的类的+load会优先调用。但在一个库之内,父、子类、类别之间调用有顺序,不同类之间调用顺序是不确定的
  • 关于继承:对于一个类而言,没有 +load 方法实现就不会调用,不会考虑对NSObject的继承,就是不会沿用父类的 +load
  • 父类和本类的调用:父类的方法优先于子类的方法。一个类的+load方法不用写明[super load],父类就会收到调用。
  • 本类和Category的调用:本类的方法优先于类别(Category)中的方法。Category的+load也会收到调用,但顺序上在本类的+load调用之后。
  • 不会直接触发initialize的调用。

initialize

+initialize 方法是在类或它的子类收到第一条消息之前被调用的,这里所指的消息包括实例方法和类方法的调用,并且只会调用一次。initialize方法实际上是一种惰性调用,也就是说如果一个类一直没被用到,那它的initialize方法也不会被调用,这一点有利于节约资源。
调用方式:runtime使用了发送消息objc_msgSend的方式对+initialize方法进行调用。也就是说+initialize方法的调用与普通方法的调用是一样的,走的都是发送消息的流程。换言之,如果子类没有实现+initialize方法,那么继承自父类的实现会被调用;如果一个类的分类实现了+initialize` 方法,那么就会对这个类中的实现造成覆盖。

要点:

  • initialize的自然调用是在第一次主动使用当前类的时候。
  • 在initialize方法收到调用时,运行环境基本健全。
  • 关于继承:和load不同,即使子类不实现initialize方法,会把父类的实现继承过来调用一遍,就是会沿用父类的+initialize。(沿用父类的方法中,self还是指子类)。
  • 父类和本类的调用:子类的 +initialize 将要调用时会激发父类调用的+initialize 方法,所以也不需要在子类写明 [super initialize]。(本着除主动调用外,只会调用一次的原则,如果父类的 +initialize 方法调用过了,则不会再调用)
  • 本类和Category的调用:Category中的 +initialize 方法会覆盖本类的方法,只执行一个Category的 +initialize 方法。

note:

  • 在使用时都不要过重地依赖于这两个方法,除非真正必要。
  • 谨慎在分类中实现+initialize方法,因为如果在分类中实现了,本类实现的+initialize方法将不会被调用。
  • 谨慎在分类中实现+load方法。因为如果在本类中实现+load方法混淆A、B两个方法,分类中也混淆A、B,因为本类和分类的+load都实现了,所以都会调用,A、B在本类中置换后,又在分类中置换了回来。
  • load方法通常用来进行Method Swizzle,initialize方法一般用于初始化全局变量或静态变量。
  • load和initialize方法内部使用了锁,因此它们是线程安全的。实现时要尽可能保持简单,避免阻塞线程,不要再使用锁。

二、KVC 和 KVO

https://github.com/leejayID/KVC-KVO/blob/master/README.md

• 合并两个有序数组

• 二叉树的反转

• 线程和进程的区别

• 堆和栈的区别

• 介绍下iOS中的多线程

• GCD手动创建的线程和GCD提供的API线程有啥关系

• 有读过GCD的源码吗

• 挑一个比较典型的项目进行分享

• iOS中开发有哪些调优策略

• KVO和KVC是什么

• 工厂模式是什么

• 工厂模式和抽象工厂的区别

• 单例模式如何设计

• 多线程有哪些

• GCD中信号量怎么使用

• 一个队列负责插入数据操作,一个队列负责读取操作,同时操作一个存储的队列,如何保证顺利进行

• 原型模式

今日头条二面

• 实现一个LUR Cache,包含读、写两个操作

• block相关

• 发送网络请求

• MVVM

• KVO

• 消息机制

什么情况使用weak关键字,相比assign有什么不同?

链如何让自己的类用copy修饰符?如何重写带copy关键字的setter?

深拷贝与浅拷贝分别是什么?

@property的本质是什么?ivar、getter、setter是如何生成并添加到这个类中的?

今日头条三面

算法

• 查找两个节点的最近公共父节点

• 相比上次来面试提高了什么

• 来段英文介绍

• 拿过哪些offer

• 为什么选择去天天狼人杀

• AFNetworking的源码架构

• 自己如何设计网络库

• Masonry源码架构

• TCP的三次握手

• TCP的四次挥手