iOS Category原理

Category:分类。

1、Category的使用场合是什么?

答:当需要将一个类拆分的时候使用。

2、Category的实现原理?

答:Category编译之后的底层结构是结构体struct category_t,里面存储着分类的对象方法、类方法、属性、协议信息。

程序运行的时候,Runtime 会将Category的信息合并到类信息中(class类对象、mate-class元类对象),后合并的分类数据会插入到原来数据的前面;

分类没有自己的class对象、和mate-class对象,因为一个类只有一个class对象、mate-class对象。

3、Category和Class Extension的区别是什么?

答:Class Extension是在编译的时候,它的数据都已经包含在类信息中了;
Category是在运行的时候,才将数据合并到类信息中。

4、Category中有+load方法吗?+load方法什么时候调用?+load方法能继承吗?

答:有+load方法。

+load方法会在Runtime加载类、分类的时候调用;

每个类的+load方法只会调用一次;

先调用类的+load方法,(按照编译顺序,先编译,先调用),调用子类的+load方法之前,会先调用父类的+load方法;

再调用分类的+load方法,(按照编译顺序,先编译,先调用)。

这里+load方法调用的顺序比较特别,没有先调用分类的+load方法,因为+load方法的调用机制不是o bjec_msgSend的方式,+load是直接找到方法地址进行调用的。

load方法能继承,不过一般不会手动调用load方法,都是系统自动调用。

5、+intialize方法什么时候调用?

答:+intialize方法会在类第一次接收到消息的时候调用(eg:alloc方法);

先调用父类+intialize,再调能用子类的+intialize,先初始化父类,再初始化子类,每个类只会初始化1次(除父类),但是如果子类没有实现+intialize,会调用父类的+intialize,所以父类的+intialize可能会被调用多次;

+intialize是通过objc_msgSend进行调用的,是通过class类对象的isa找到mate-class元类对象里的+intialize方法进行调用,所以分类的+intialize方法会覆盖本身的+intialize。

6、Category能否添加成员变量,如果可以,如何给Cagegory添加成员变量?

答:默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中,但可以通过关联对象的方法来间接实现。

给分类添加属性时,分类会自动声明setter、getter方法,但是不会添加成员变量、也不会实现setter、getter方法。

可以通过Runtime API提供的C语言方法:

//添加关联对象

  • (void)setAge:(NSInteger)age
    {
    objc_setAssociatedObject(self, @selector(age), @(age), OBJC_ASSOCIATION_ASSIGN);
    }

//获得关联对象

  • (NSInteger)age{
    return [objc_getAssociatedObject(self, _cmd) integerValue];
    }

//@selector(age) 指的是age方法的内存地址
//_cmd 是当前方法的内存地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值