iOS面试题3

7. Category的实现原理
  • Category编译之后的底层结构是struct Category_t,里面存储着分类的属性,实例方法,类方法,协议信息
  • 在程序运行的时候,runtime会将Category的数据,合并到类信息中,注意,在合并的过程中,分类的方法会被方法列表的数组前面位置,最后编译的分类,放在方法列表数组的第一位,这将会导致同样的方法,如果在分类和类中都实现,分类方法的优先级高

Category的底层实现
Category的底层实现

8.Category和Extension的区别是什么?
  • Extension 在程序编译的时候,它的数据就已经包含在类信息中了
  • Category 在程序运行的时候,通过runtime将分类中数据合并到类信息中去
9.Category中load方法什么时间调用?
  1. load方法会在runtime加载分类的时候调用;
  2. 每个分类的load方法,在程序运行过程中只会调用一次
  3. load方法是通过函数指针直接调用的,不走objc_msgSend()方法

调用顺序

  1. 先调用类的load方法
    1. 按照编译的顺序进行调用(先编译,先调用)
    2. 在调用子类的load方法之前,一定先调用父类的load方法
  2. 在调用分类的load方法
    1. 按照编译的顺序进行调用(先编译,先调用)

如果我们主动调用load方法,需要注意

主动调用load方法

分析:

  1. load方法只会被调用一次,而且调用时间是在runtime加载类的时候就被调用.
  2. 而当我们主动调用子类的load方法,这时候其实是走objc_msgSend(),先通过isa指针去找方法列表,如果isa没有找到,就会再通过superclass指针去找父类方法列表,这时候父类方法列表中有分类的方法和它本身的方法,首先加载分类的方法.
10. initialize方法和load方法的不同
  1. 调用机制不同
  • load是根据函数指针地址直接调用
  • initialize是通过objc_msgSend()方法调用

2.调用时刻不同

  • load是runtime加载类,分类的时候调用(只会调用一次)
  • initialize是类第一次收到消息的时候进行调用,一个类的initialize方法只会调用一次(父类的可能会被调用多次)
  1. 调用顺序不同

load

  1. 先调用类的load方法
    a. 先编译的类先调用
    b. 调用子类的load方法之前,会先调用父类的load方法
  2. 在调用分类的load方法
    a. 先编译的类,先调用load方法

initialize

  1. 先初始化父类的initialize方法
  2. 在初始化子类的initialize方法 (如果子类没有实现initialize方法,会调用父类的initialize方法)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值