主题三《Category、关联对象》

2020-08-12  本文已影响0人  东方奇迹
截屏2020-08-05 下午10.04.08.png 截屏2020-08-05 下午10.04.53.png 截屏2020-08-05 下午10.10.12.png 截屏2020-08-05 上午11.07.50.png 截屏2020-08-05 下午1.38.51.png 截屏2020-08-05 下午2.55.27.png 截屏2020-08-05 下午5.38.34.png

注意:给分类添加的属性只会生成set方法和get方法的声明,并不会生成成员变量和set方法及get方法的实现,为了让分类属性的用法和原来类里面的用法保持一致,这样写属性才有意义,所以可使用下边方法来实现:

截屏2020-08-07 上午10.06.02.png

注意:上面的方法写起来会很麻烦,还要注意加上同步锁防止多线程抢夺资源的情况,所以采用另外一种方法关联对象来实现

截屏2020-08-07 上午10.19.55.png 截屏2020-08-07 上午10.46.11.png 截屏2020-08-07 上午10.25.38.png 截屏2020-08-07 上午11.11.21.png 截屏2020-08-07 下午2.00.16.png 截屏2020-08-07 上午10.45.13.png 截屏2020-08-07 上午10.50.12.png 截屏2020-08-07 上午10.56.11.png 截屏2020-08-07 上午10.57.56.png

1、Category的实现原理(Category底层结构及Category的加载处理过程)?

2、Category和Class Extension的区别?

3、load、initialize方法的区别(调用方式、调用时机、顺序)?


1.调用方式
1> load是根据函数地址直接调用
2> initialize是通过objc_msgSend调用

2.调用时刻
1> load是runtime加载类、分类的时候调用(只会调用1次)
2> initialize是类第一次接收到消息的时候调用,每一个类只会initialize一次(父类的initialize方法可能会被调用多次)

3.load、initialize的调用顺序?
(1).load
1> 先调用类的load
a) 先编译的类,优先调用load
b) 调用子类的load之前,会先调用父类的load

2> 再调用分类的load
a) 先编译的分类,优先调用load

(2).initialize
1> 先初始化父类
2> 再初始化子类(可能最终调用的是父类的initialize方法)
3> 如果分类实现了initialize方法就会覆盖类本身的initialize方法调用

4、通过关联对象给分类添加属性?

- (void)setName:(NSString *)name
{
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name
{
    // 隐式参数
    // _cmd == @selector(name)
    return objc_getAssociatedObject(self, _cmd);
}

上一篇下一篇

猜你喜欢

热点阅读