美文网首页
Category场景、继承与多态

Category场景、继承与多态

作者: 厨子 | 来源:发表于2019-07-12 16:59 被阅读0次

    实例变量 = 成员变量 = ivar

    category使用场景

    1. 为源码文件添加方法
    2. 按功能进行分类,放到多个文件中
    3. 第二点带来的好处:减小单个文件大小、方便多人开发同一个类、按需加载需要的 category

    可以参考苹果的 UIKit 库中,就使用了很多的 category

    category不可为

    typedef struct category_t {
        const char *name;  //类名
        classref_t cls;         
        struct method_list_t *instanceMethods;  //category中添加的实例方法
        struct method_list_t *classMethods;       //category中添加的类方法
        struct protocol_list_t *protocols;             //category实现的协议
        struct property_list_t *instanceProperties;  //category中添加的属性
    } category_t;
    

    从结构体中看,category 可以添加实例方法类方法协议属性,但不可添加实例变量(带下划线的实例变量)

    由于 @property的本质是

    @property = ivar(实例变量) + getter + setter;
    

    而在 category 中使用 @property 声明的属性,并不会自动生成 gettersetter 方法,以及 _ivar(所以一般说 category 不能声明属性). 当打点调用该属性时,编译没有问题(因为category是运行期决定),但运行起来走到调用的地方,必定报错:

    [XXX xx]: unrecognized selector sent to instance X
    

    Extension

    Extension 通常存在于某个类的 .m 文件中,以下面的形式存在

    @interface ABC()
    ///属性和方法声明
    @end
    

    也可以单独创建一个Extension 文件(只有.h),该文件可以通过下面步骤创建:
    新建文件->Object-C文件->文件类型选 Extension -> 然后选择所属的类

    Extension 可以声明方法属性实例变量

    Category 与 Extension区别

    1. Extension 可以添加实例变量Category不可以,因为在运行期,对象的内存布局已经确定,如果添加实例变量会破坏类的内部布局,这对编译性语言是灾难性的
    2. Extension 在编译期决定,Category 在运行期决定怎么生成属性方法等
    3. 只能为源码文件添加 Extension,添加 Category 不需要知道源码文件

    继承与多态

    OC中的继承是单继承。即一个类至多只能有一个父类。子类继承父类的属性和方法,子类可以重写父类的方法。

    多态 借助于动态绑定:动态类型能使程序直到运行时才确定对象所属的类型。动态类型绑定能使程序直到运行时才确定对象要调用的方法

    在模拟多态的场景,需要两个条件:
    - 继承
    - 父类指针接收子类的对象

    使用父类指针接收子类对象,可以带来两个好处:
    - 该指针对象可以调用父类的所有方法和属性
    - 如果该指针对象调用了子类的方法和属性,也不会引起报错,如果反过来了,子类指针接收了父类对象,那么当调用子类的方法或属性时,必定报错

    因此,由于多态的存在,在编写程序时,如果不知道某个参数具体是哪个子类类型,那么,可以把该参数类型统一写成其父类的类型,接收后,再判断能调用哪些方法或属性。

    相关文章

      网友评论

          本文标题:Category场景、继承与多态

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