为Category添加属性

2017-08-01  本文已影响32人  _Choice_

前言

在iOS开发中,category作用十分巨大,在实际项目中,我们可以通过添加一个类的category来实现任意地方调用我们已经准备好的方法,或者是对现有的一些类进行扩展。
最常见的应用莫过于为ViewController添加分类,在分类中准备好方法,这样一来我们可以在任意控制器去调用我们准备好的方法。
由于catagory的特性,使得我们在其中只能添加方法并不能添加属性,这大大限制了我们的使用。

好在Objective-C的动态特性为我们带来了希望。
本文通过利用Objective-C的动态特性,在运行时动态添加属性,动态绑定,达到category中添加属性的目的。

分析

首先,我们先看一下property的构成
@property的本质其实是 ivar(实例变量)+getter+setter
也就是说,为category添加属性的方法,其本质上是我们人为创造一个property,通过准备实例变量,自行实现setter方法和getter方法,来达到目的。

接下来我们看看需要用到的runtime部分。

OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);

OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)
    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);

objc_getAssociatedObject

这个方法中需要用到两个参数,objectkey
由于当前方法在分类中,并且我们获取的属性也是当前类下的属性,object这边指的是self
而这里的key代表的是属性的标记,通过这个key来查找对应的属性。

//key的写法
1、static void *key = &key;

2、static NSString *const key = @"key"; 

3、static char const * const key = "key";

objc_setAssociatedObject

这个方法中前两个参数同上,后两个参数分别代表关联的属性,和关联策略。

关联属性策略如下,根据实际使用选择关联策略。

enum {
    OBJC_ASSOCIATION_ASSIGN = 0, //关联对象的属性是弱引用 

    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //关联对象的属性是强引用并且关联对象不使用原子性

    OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //关联对象的属性是copy并且关联对象不使用原子性

    OBJC_ASSOCIATION_RETAIN = 01401, //关联对象的属性是copy并且关联对象使用原子性

    OBJC_ASSOCIATION_COPY = 01403 //关联对象的属性是copy并且关联对象使用原子性
};

实例

在头文件.h中添加一个property,如:

@property (nonatomic,assign) BOOL animateInvalid;

.m实现:

static char const * const kanimateInvalid = "kanimateInvalid";
#import <objc/runtime.h>

@implementation UIViewController (Associate)
@dynamic animateInvalid;//手动实现getter和setter

- (BOOL)animateInvalid{
    return [objc_getAssociatedObject(self, kanimateInvalid) boolValue];
}

- (void)setAnimateInvalid:(BOOL)animateInvalid{
    objc_setAssociatedObject(self, kanimateInvalid, @(animateInvalid), OBJC_ASSOCIATION_ASSIGN);
}

至此在category中添加属性已经完成。掌握方法在实际项目中能够发挥十分大的作用,大大提高我们编程的效率。

上一篇 下一篇

猜你喜欢

热点阅读