objectiveC中Category分类你知多少
在OC 中,使用category会让我们在开发中非常方便,可以为某个类增添方法,对类别自己有一点小小的体会,首先先来介绍一下类别1.分类的创建:
1.类别的作用
(1)可以将类的实现分散到多个不同的文件或者不同的框架中,方便代码的管理。也可以对框架提供类的扩展(没有源码,不能修改)。
(2)创建对私有方法的前向引用:如果其他类中的方法未实现,在你访问其他类的私有方法时编译器报错这时使用类别,在类别中声明这些方法(不必提供方法实现),编译器就不会再产生警告
(3)向对象添加非正式协议:创建一个NSObject的类别称为"创建一个非正式协议",因为可以作为任何类的委托对象使用。
2.局限性
(1)分类只能增加方法,不能增加成员变量,但是可以通过运行时来给分类添加属性,那么成员变量和属性有什么区别呢?
(2)如果分类和原来类出现同名的方法, 优先调用分类中的方法,原来类中的方法会被忽略,方法调用的优先级(从高到低) 分类(最后参与编译的分类优先),只要有分类就优先调用分类,不考虑与主类的编译顺序
(3)方法的调用优先级:分类-->原来的类-->父类,若包含多个类,则最后参与编译的分类优先执行类别的特点:
类别是在运行时决定的,在运运行时才会分配相应的内存空间,在就决定了在编译期是不能给某个类增加属性,否则会影响内存布局,从而导致crash ,若想给某个类增加一个属性,需要在运行时添加,首先先介绍下类别的结构:typedef struct category_t { const char *name; classref_t cls; struct method_list_t *instanceMethods; struct method_list_t *classMethods; struct protocol_list_t *protocols; struct property_list_t *instanceProperties; } category_t;
这个结构体理念包含这个类别的名字,实例方法,类方法,协议名,和实例属性
正如我们所知的那样,当我们重写类的一个方法以后,会覆盖原来类的方法,它为什么会覆盖原来类的方法呢,我们先来看一下当调用一个方法的时候是怎么运行的BOOL classExists = NO; if (cat->instanceMethods || cat->protocols || cat->instanceProperties) { addUnattachedCategoryForClass(cat, cls, hi); if (isRealized(cls)) { remethodizeClass(cls); classExists = YES; } if (PrintConnecting) { _objc_inform("CLASS: found category -%s(%s) %s", getName(cls), cat->name, classExists ? "on existing class" : ""); } } if (cat->classMethods || cat->protocols /* || cat->classProperties */) { addUnattachedCategoryForClass(cat, cls->isa, hi);//关联映射 if (isRealized(cls->isa)) { remethodizeClass(cls->isa);//添加事件 } if (PrintConnecting) { _objc_inform("CLASS: found category +%s(%s)", getName(cls), cat->name); } } 可以减少单个文件的体积可以把不同的功能组织到不同的Category里可以由多个开发者共同完成一个类,我们在开发时,会给自己写的一些分类直接拖入项目中。提高开发的效率。可以按需加载想要的category利用runtime给分类添加属性:
实际上,Category实际上允许添加属性的,同样可以使用@property,但是不会生成_变量(带下划线的成员变量),也不会生成添加属性的getter和setter方法,所以,尽管添加了属性,也无法使用点语法调用getter和setter方法。但实际上可以使用Runtime去实现Category为已有的类添加新的属性并生成getter和setter方法。//创建一个NSArray的Category,NSArray+MyCategory.h文件: // NSArray+MyCategory.h #import @interface NSArray (MyCategory) //不会生成添加属性的getter和setter方法,必须我们手动生成 @property (nonatomic, copy) NSString *blog; @end// NSArray+MyCategory.m文件:
// NSArray+MyCategory.m文件: #import "NSArray+MyCategory.h" #import @implementation NSArray (MyCategory) // 定义关联的key static const char *key = "blog"; /** blog的getter方法 */ - (NSString *)blog { // 根据关联的key,获取关联的值。 return objc_getAssociatedObject(self, key); } /** blog的setter方法 */ - (void)setBlog:(NSString *)blog { // 第一个参数:给哪个对象添加关联 // 第二个参数:关联的key,通过这个key获取 // 第三个参数:关联的value // 第四个参数:关联的策略 objc_setAssociatedObject(self, key, blog, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end// 测试代码 -(void)categoryTest{ NSArray *myArray = [[NSArray alloc]init]; myArray.blog = @"https://www.jianshu.com/p/e24bd3ee4ef4"; NSLog(@"Category添加属性。 用Category为NSArray添加了一个blog属性,blog=%@",myArray.blog); } ---------------------------------------------------- // 打印结果 ----> Category添加属性。 用Category为NSArray添加了一个blog属性,blog=https://www.jianshu.com/p/e24bd3ee4ef4
使用注意:分类只能增加方法,不能增加实例变量。(但是可以利用Runtime的关联对象)分类方法实现中可以访问原来类中声明的成员变量。分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用(实际上并没有真的替换,而是Category的方法被放到了新方法列表的前面,而原来类的方法被放到了新方法列表的后面,这也就是我们平常所说的Category的方法会"覆盖"掉原来类的同名方法,这是因为运行时在查找方法的时候是顺着方法列表的顺序查找的,它只要一找到对应名字的方法,就会罢休,殊不知后面可能还有一样名字的方法)。当分类、原来类、原来类的父类中有相同方法时,方法调用的优先级:分类(最后参与编译的分类优先) –> 原来类 –> 父类,即先去调用分类中的方法,分类中没这个方法再去原来类中找,原来类中没有再去父类中找。如果多个category中存在同名的方法,运行时到底调用哪个方法由编译器决定,最后一个参与编译的方法会被调用。Category是在runtime时候加载,而不是在编译的时候。
Extension与Category区别Extension在编译器决议,是类的一部分,在编译器和头文件的@interface和实现文件里的@implement一起形成了一个完整的类。伴随着类的产生而产生,也随着类的消失而消失。Extension一般用来隐藏类的私有消息,你必须有一个类的源码才能添加一个类的Extension,所以对于系统一些类,如NSString,就无法添加类扩展Category是运行期决议的类扩展可以添加实例变量,分类不能添加实例变量(原因:因为在运行期,对象的内存布局已经确定,如果添加实例变量会破坏类的内部布局,这对编译性语言是灾难性的。
。
比特币能否取代黄金和美元,成为世界普遍认可和通行的货币?比特币有可能成为黄金一样的世界资产,但不可能成为美元一样的世界货币。比特币的固定上限设计使得它有可能成为类似于黄金一样的是世界资产。如果全球范围内的投机力量比特币的真正使用者,以及
算法,你手机中最大的骗子,这个世界充满欺骗四大数据推送如今已经不是什么新鲜事了,稍微关注媒体新闻的或多或少都会知道自己一直在被大数据推送着。只要你在聊天里提及了某件物品,或者随意点开某件物品的链接,包括你的搜索,只要你有对外
车用芯片产能恐缺到2023年俄罗斯开发先进武器因制裁被削弱传苹果新iPhoneSE下周韩国上市韩国电信运营商18日表示,苹果公司将于下周五(25日)在韩国推出最新升级版的iPhoneSE智能手机,价格为59万韩元(约480美元),并于18
减少机型做精品,加大投入增实力尽管受到新冠肺炎疫情冲击,近年来国产手机新品上市的脚步并未停歇,国内主流手机厂商纷纷发力中高端市场,减少机型做精品已成不少手机厂商的共识。中国信通院最新发布的数据显示,虽然今年前2
有哪些好看的背景图呢?不请自来有哪些好看的背景图呢?哈哈,又到了发图片的时候了,最近攒积了一些在手机里,正愁没得分享的,现在就把它们都分享出来吧那么就请你往下看,看看有没有你喜欢的吧因为图片风格类型各有
我写的Python代码,同事都说好人生苦短,我用Python。程序员的追求就是不写代码,早日财务自由。不对,一不小心把实话说出来了,应该是将代码写得简洁,优雅。Python程序员的追求则是Pythonic,正好在P
蔚来新品牌的业务工作进展顺利未来加大自动驾驶等领域研发蔚来新品牌的业务工作进展顺利未来加大自动驾驶等领域研发科创板日报25日讯,在2021年Q4财报会议上,蔚来方面表示,位于合肥新桥智能汽车产业园区的第二生产基地的厂房建设和设备安装已
1500元左右,三款综合性能强悍的手机配置解读在1500元挡位中能够选择的手机很多,但有这么三款高性能强续航的机型值得大家简单了解一下。为此,在这里借此平台给大家带来以下三款综合性能优秀的手机配置解读,以方便大家深度熟悉这三款
nginx为什么性能这么优越?所谓没有对比就没有伤害!在nginx横空出世之前,Apache服务器一直占据web服务器的垄断地位,所以就用对比的方式来解释nginx那么强!两者性能差别的主要原因在于网络IO模型
笔记本ALIENWAREx14闪亮登场,性能和纤薄双管齐下想要让性能和纤薄这两个词同时出现在一台笔记本电脑上这可不是一件什么容易的事,但是ALIENWARE的X系列新成员ALIENWAREx14却做到了。ALIENWAREx14突破性的1
马斯克特斯拉ModelY将迎来两个新颜色,采用多层车漆IT之家3月23日消息,特斯拉CEO埃隆马斯克宣布,将通过其位于柏林超级工厂的油漆车间提供两种新的车漆颜色。早在ModelS的早期,特斯拉曾经为汽车提供多种颜色,但之后简化了可选项