iOS进阶之类别(Category)(9)

类别使用场景
  • 见解一
    Category的主要作用是为已经存在的类添加方法。
    Objective-C 中的 Category 就是对装饰模式的一种具体实现。它的主要作用是在不改变原有类的前提下,动态地给这个类添加一些方法。

  • 见解二
    Category类别是Objective-C语言中提供的一个灵活的类扩展机制。类别可以在不获悉、不改变原来代码的情况下往一个已经存在的类中添加新的方法。类别只能添加新的扩展方法,而不能添加新的属性。类别扩展的新方法有更高的优先级,会覆盖同名的原类的已有方法。

优点

  • 声明私有方法
  • 分解体积庞大的类文件
  • 把Framework私有方法公开
  • 模拟多继承(另外可以模拟多继承的还有protocol)
  1. 当你在使用基础类库中的类时,你不想继承这些类而只想添加一些方法时。
  2. 相对于子类继承扩展,类别的另一明显优势是实现了功能的局部化封装,扩展的功能只会在本类被引用时看到。例如,假设原类为UIButton,现在要使用类别扩展一些用于模块A的方法,那么这些扩展方法就可以定义在一个叫做UIButton+A.h的头文件中,只有在引用UIButton+A.h的地方,才能看到原UIButton类有模块A添加的那些扩展方法,如果不需要模块A的功能,不引用UIButton+A.h头文件就看不到UIButton的那些扩展方法的存在,实现扩展模块的隔离。
Category源码:
Category 是表示一个指向分类的结构体的指针,其定义如下:
typedef struct objc_category *Category;
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; // 分类所实现的协议列表
}

我们可以看到,他是有实例方法列表,类方法列表,但是就是没有属性列表。
所以,原则上它只能增加方法,不能增加成员(实例)变量。如果要扩展类的属性,OC作为一个有动态性的语言,用到运行时编程,必须使用<obj/runtime.h>,使用objc_getAssociatedObject,objc_setAssociatedObject以及objc_removeAssociatedObjects.

扩展类别(Category)属性

示例代码如下:

1、先创建一个person类

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic, copy) NSString *name;

@end

#import "Person.h"

@implementation Person

@end

2、新建一个分类,运用associative添加属性

#import "Person.h"

@interface Person (addproty)

@property(nonatomic, copy)NSString *addr;

@end

#import "Person+addproty.h"
#import <objc/runtime.h>

@implementation Person (addproty)

static char strAddrKey = 'a';

- (NSString *)addr
{
    return objc_getAssociatedObject(self, &strAddrKey);
}

- (void)setAddr:(NSString *)addr
{
    objc_setAssociatedObject(self, &strAddrKey, addr, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

@end

category、extension区别
  • 分类中原则上只能增加方法(能添加属性的的原因只是通过runtime解决无setter/getter的问题而已);
  • 类扩展的方法是一定要实现的方法。Category没有这个限制。这是因为类扩展是在编译阶段被添加到类中,而类别是在运行时添加到类中。
  • Category的方法不一定非要在@implementation中实现,也可以在其他位置实现,但是当调用Category的方法时,依据继承树没有找到该方法的实现,程序则会崩溃。
参考

iOS扩展类属性总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值