美文网首页
OC基础-Category类别 、extension类扩展(八)

OC基础-Category类别 、extension类扩展(八)

作者: 浮华_du | 来源:发表于2021-08-31 17:07 被阅读0次

    category是Objective-C 2.0之后添加的语言特性,category的主要作用是为已经存在的类添加方法.
    可以看下美图技术团队的这篇文章

    1.创建Category
    image.png image.png
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface NSString (NSString_NumberConvenience)
    -(NSNumber *)lengthAsNumber;
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    #import "NSString+NSString_NumberConvenience.h"
    
    @implementation NSString (NSString_NumberConvenience)
    - (NSNumber *)lengthAsNumber{
        NSUInteger length = [self length];
        return [NSNumber numberWithUnsignedInt:length];
    }
    @end
    
    #import <Foundation/Foundation.h>
    #import "NSString+NSString_NumberConvenience.h"
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            NSLog(@"字数 %@",@"白日依山尽".lengthAsNumber);
        }
        return 0;
    }
    //字数 5
    
    2.优劣势

    优势:
    (1). 减少单个文件的体积
    (2). 把不同的功能分配到不同的分类里,便于管理
    (3). 可以按需加载想要的分类
    局限性:
    (1). 无法向类中添加新的实例变量
    (2). 类别中的方法名与现有方法重名, 名称冲突.(冲突时,类别有更高的优先级)

    3. category本质

    我们知道,所有的OC类和对象,在runtime层都是用struct表示的,category也不例外,在runtime层,category用结构体category_t(在objc-runtime-new.h中可以找到此定义),它包含了:

    1)、类的名字(name)
    2)、类(cls)
    3)、category中所有给类添加的实例方法的列表(instanceMethods)
    4)、category中所有添加的类方法的列表(classMethods)
    5)、category实现的所有协议的列表(protocols)
    6)、category中添加的所有属性(instanceProperties)
    从category的定义也可以看出category的可为(可以添加实例方法,类方法,甚至可以实现协议,添加属性)和不可为(无法添加实例变量)。

    平常都是使用分类来对系统的类封装一些小功能,如NSString判空处理等,可以看下 ibireme大神开源的这个库YYCategories,都是针对系统的类使用分类拓展的小功能,很实用。再来看看业界闻名的空白页框架DZNEmptyDataSet,它就是通过对 UIScrollView使用分类功能,非常完美、无侵入的解决了无数据时,避免白屏的尴尬,改善用户体验。

    二. 类扩展(extension)

    extension的别名有很多,扩展、延展、匿名分类。它就是类的一部分,在编译期和头文件里的@interface以及实现文件里的@implement一起形成一个完整的类,它伴随类的产生而产生,亦随之一起消亡。
    我们平时在.m文件里使用的

    @interface ViewController ()
    //私有属性
    //私有方法
    @end
    
    1. Extension的作用

    声明私有属性
    声明私有方法
    声明私有成员变量

    2. Extension的特点

    编译时决议
    只以声明的形式存在,多数情况下寄生在宿主类的.m中
    一般的私有属性写到.m文件中的类扩展中
    不能为系统类添加扩展

    Category和Extension的区别

    extension 在编译期决议, category在运行期决议。

    • 分类是运行时决议;扩展是编译时决议;(所以扩展中声明的方法没有被实现,编译器会报警,但是分类种的方法没有被实现编译器是不会有任何警告的)
    • 分类原则上只能增加方法,并且是公开的(无法直接添加属性,可以通过runtime添加属性,原因通过runtime可以解决无setter/getter的问题);扩展能添加方法,实例变量,默认是@private类型的,且只能作用于自身类,而不是子类或者其他地方;
    • 分类有自己的实现部分;扩展无自己的实现部分,只能依托对应类的实现部分来实现;
    • 分类可以为系统类添加分类;扩展不可以为系统类添加扩展(必须有一个类的源码才能添加一个类的Extension);所以你无法为系统的类比如NSString添加extension
      定义在 .m 文件中的类扩展方法为私有的,定义在 .h 文件(头文件)中的类扩展方法为公有的。类扩展是在 .m 文件中声明私有方法的非常好的方式。
      (详见(https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html))

    相关文章

      网友评论

          本文标题:OC基础-Category类别 、extension类扩展(八)

          本文链接:https://www.haomeiwen.com/subject/nynbvltx.html