category && extension 介绍

category && extension 介绍

1、category 分类
  • 介绍

    利用Objective-C的动态运行时分配机制,Category提供了一种比继承(inheritance)更为简洁的方法来对class进行扩展,无需创建对象类的子类就能为现有的类添加新方法,可以为任何已经存在的class添加方法,包括那些没有源代码的类(如某些框架类)。

  • 原理

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

    • 类的名字(name)

    • 类(cls)

    • category中所有给类添加的实例方法的列表(instanceMethods)

    • category中所有添加的类方法的列表(classMethods)

    • category实现的所有协议的列表(protocols)

        struct objc_category {
            char *category_name                                      OBJC2_UNAVAILABLE;
            char *class_name                                         OBJC2_UNAVAILABLE;
            struct objc_method_list *instance_methods                OBJC2_UNAVAILABLE;
            struct objc_method_list *class_methods                   OBJC2_UNAVAILABLE;
            struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
        }   
      
  • 特点

    • 拆分类,降低类的复杂度
    • 扩展类的方法,比如系统自带类
    • 不能添加实例变量
  • 使用 在h文件中添加方法,m文件中实现方法就ok了

2、extension 扩展

Extension常被称为是匿名的Category 用于给类添加新方法,但只作用于原始类,不作用于subclass 只能对有implementation源代码的类写Extension,对于没有implementation源代码的类,比如framework class,是不可以的 Extension可以给原始类添加新方法,以及新属性 类目(category)可以给系统已有类添加扩展方法但是不能添加属性,并且被添加的方法可以被此类的子类所继承;延展(extension)为我们的自定义类添加属性和方法,但是添加的属性和方法都是私有的,在此类的子类中是无法访问的。

extension在编译期决议,它就是类的一部分,在编译期和头文件里的@interface以及实现文件里的@implement一起形成一个完整的类,它伴随类的产生而产生,亦随之一起消亡。extension一般用来隐藏类的私有信息,你必须有一个类的源码才能为一个类添加extension,所以你无法为系统的类比如NSString添加extension

但是category则完全不一样,它是在运行期决议的。

就category和extension的区别来看,我们可以推导出一个明显的事实,extension可以添加实例变量,而category是无法添加实例变量的(因为在运行期,对象的内存布局已经确定,如果添加实例变量就会破坏类的内部布局,这对编译型语言来说是灾难性的)。

3、如何给category添加实例变量

重写set/get方法

- (NSString *)viewName {
    return (NSString *)objc_getAssociatedObject(self, viewNameKey);
}
// set方法
- (void)setViewName:(NSString *)newViewNameKey {
    objc_setAssociatedObject(self, viewNameKey, newViewNameKey, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

为什么这样可以呢?

创建关联要使用到Objective-C的运行时函数:objc_setAssociatedObject来把一个对象与另外一个对象进行关联。

转载于:https://my.oschina.net/KJhulinhua/blog/1036942

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值