OC基础-category(1)

OC基础-category(1),第1张

首先我们要明白什么是category

类扩展class extension

我们有一个ZKPerson类如下里面会有属性,以及instance方法和class方法

那什么是类扩展呢

类扩展和分类Catgory一样都是可以给类增加定义属性和方法。

我们新建ZKPerson两个分类(Test) (Eat)如下

我们再将ZKPerson+(Eat)转化成cpp文件

(xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc ZKPerson+Eatm),以便查看category的底层。

我们会发现category底层结构为一个_category_t的结构体

也就是说当我们每创建一个分类,系统在编译时候就会把这个分类转化成这样一个结构体并保存起来。

当我们在程序运行时runtime,所有分类的这些属性方法等将会合并到Person里面,分类的对象方法合并到Person类对象里面,分类的类方法合并到Person元类对象里面。runtime合并过程源码如下:

查看下attachLists是具体如何实现将分类方法加到类对象的方法列表中(原来的方法列表往后移,新的分类的方法列表放在原来的方法列表前面)

就此,我们可以看到后面合并进来的分类方法列表是放在数组的前面的,最后把所有分类的方法列表合并到原有类的方法列表前面。也就是说后编译的分类数据会在数组的前面,当我们调用时会优先调用数组前面的方法。

我们可以实践一下,编译前记得在Target-BuildPhase-Compile Sources中删除我们的cpp文件,不让它参与编译,我们调用[person run]实例方法,首先我们的编译顺序是这样的,先编译Test分类,然后时Eat分类,最后是Person类

因为Eat分类是最后编译的,所以调用的是Eat分类的run方法。虽然Person类是最后编译,但是从上述源码中看到所有分类的方法合并时是放在Person类方法列表前面的。不管Person类何时编译,只要它有分类就会把分类的方法列表合并到Person类的方法列表前面。所以我们调用时分类会覆盖Person类的方法。

总接:

1、什么时候用到category

给系统类添加方法、属性(需要关联对象)。

对某个类大量的方法,可以实现按照不同的名称归类。

2、category的实现原理

答:category编译之后的底层结构是struct category_t,里面存储着分类的对象方法,类方法,属性,协议信息,在程序运行的时候,runtime会将category的数据,合并到原有类信息中(类对象,元类对象中)

3、category的加载处理过程

答:

1)、通过Runtime加载某个类的所有category数据

2)、把所有category的方法,属性,协议数据,合并到一个大数组中,后面参与编译的category数据,会在数组的前面

3)、将合并后的分类数据(方法,属性,协议),插入到类原来数据的前面

4)、分类的调用顺序是后编译的先调用

3、category和类扩展class extension的区别?

答:category是在运行时将方法属性合并到类对象里面,而类扩展是在编译的时候就将方法属性等合并到类对象里面

内容转自于此篇华文 >

1、定义的一个类,里面有一个私有变量mt_,并且在初始化值为"HaHa Ha"。@interface Mobj : NSObject {@privateNSString mt_;}@end@implementationMobj- (id)init {self = [super init];if (self) {mt_ =[[NSString alloc] initWithString:@"Ha Ha Ha"];}return self;}- (void) dealloc {[mt_ release];记得加头文件#import<objc/runtimeh):NSStringstr;Mobj obj =[[Mobj alloc] init];object_getInstanceVariable(obj, "mt_", (void)&str);Ok,这样就实现了私有变量的访问。

浅拷贝:

1指针拷贝,没有开辟新的内存;

2生成一个新的指针变量指向原有对象的地址;

3原有对象引用计数+1。

深拷贝:

1从堆中开辟一份新的内存给新的对象,并将原有对象的信息赋值给新的对象;

2生成一个新的指针变量指向新的对象;

3原有对象引用计数不会增加,新的对象引用计数为1。

完全拷贝:

1是对多层对象包含或者集合中存储对象而言的;

2被拷贝对象的每一层都进行了深拷贝;

3例如集合中的对象,对象中的对象等。

  示例:

  打印输出:

结论:

  示例:

  打印输出:

结论:

  示例:

  打印输出:

结论:

  示例:

  打印输出:

结论:

  在OC中不是所有的类都支持拷贝,只有遵循 NSCopying 才支持copy,只有遵循 NSMutableCopying 才支持mutableCopy。

  NSObject有一个实列方法叫做 - (id)copy 。在OC源码中可以看到,默认的copy方法调用为:

  对于采纳了 NSCopying 协议的子类,需要实现 copyWithZone 方法,否则会引发异常。 NSMutableCopying 只有在MRC模式下使用。

示例:

结论:

自定义类通过重写 copyWithZone 方法实现了深拷贝,通过 copy 方法(该方法默认调用 copyWithZone 方法)复制得到p1,从结果可以看出:深复制对象和和源对象的地址是不一样的。

NSCoping官方文档

自定义对象的copy和mutableCopy

类别 是一种为现有类添加新方法的方式,我们有时可以见到 “类名称+类别名称” 的命名方式。

类别可以添加属性 property ,但是不能添加实例变量。

下面我们来创建一个基于UILabel的类别,增加一个自适应Label的方法~

这里我特意添加前缀 kimi ,来避免方法名称冲突。

该方法作用是根据 content 内容实现 UILabel 的自动换行和调整字体发小,使Label能够合理显示内容。

运行可以看到效果, selflabel 实现了自适应字体大小和换行:

以上就是关于OC基础-category(1)全部的内容,包括:OC基础-category(1)、OC 类的结构分析、如何从oc中去获取一个私有的变量.....等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9822414.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存