您的位置:首页 > 其它

分类到底能不能添加属性?

2016-03-12 12:15 405 查看
文/碧霄问鼎(简书作者)原文链接:http://www.jianshu.com/p/3cbab68fb856著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。“通过运行时,分类是可以在不添加成员变量的情况下添加属性的!”遇到一个问题,写了一个分类,但原先类的属性不够用。添加一个属性,调用的时候崩溃了,说是找不到getter、setter方法。查了下文档发现,OC的分类允许给分类添加属性,但不会自动生成getter、setter方法。有没有解决方案呢?有,通过运行时建立关联引用。接下来以添加一个这样的属性为例:
@property (nonatomic, copy) NSString *str;
1、引入运行时头文件。
#import <objc/runtime.h>
2、在匿名分类或者头文件中添加属性。区别是:匿名分类中添加的是私有属性,只在本类中可以使用,类的实例中不可以使用。头文件中添加的在类的实例中也可以使用。
//分类的头文件
@interface ClassName (CategoryName)
//我要添加一个实例也可以访问的变量所以就写在这里了
@property (nonatomic, strong) NSString *str;
@end

//匿名分类
@interface ClassName ()

@end
3、在实现里面写要添加属性的getter、setter方法。
@implementation ClassName (CategoryName)

-(void)setStr:(NSString *)str
{
objc_setAssociatedObject(self, &strKey, str, OBJC_ASSOCIATION_COPY);
}

-(NSString *)str
{
return objc_getAssociatedObject(self, &strKey);
}
@end
setStr:
方法中使用了一个
objc_setAssociatedObject
的方法,这个方法有四个参数,分别是:源对象,关联时的用来标记是哪一个属性的key(因为你可能要添加很多属性),关联的对象和一个关联策略。用来标记是哪一个属性的key常见有三种写法,但代码效果是一样的,如下:
//利用静态变量地址唯一不变的特性
1、static void *strKey = &strKey;

2、static NSString *strKey = @"strKey";

3、static char strKey;
关联策略是个枚举值,解释如下:
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并且关联对象使用原子性
};
4、完成后的整体代码如下:.h文件
//分类的头文件
@interface ClassName (CategoryName)
@property (nonatomic, strong) NSString *str;
@end
.m文件
//实现文件
#import "ClassName + CategoryName.h"
#import <objc/runtime.h>

static void *strKey = &strKey;

@implementation ClassName (CategoryName)
-(void)setStr:(NSString *)str
{
objc_setAssociatedObject(self, & strKey, str, OBJC_ASSOCIATION_COPY);
}

-(NSString *)str
{
return objc_getAssociatedObject(self, &strKey);
}
@end

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: