给分类(Category)添加属性

遇到一个问题,写了一个分类,但原先类的属性不够用。添加一个属性,调用的时候崩溃了,说是找不到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

  

时间: 2024-10-11 14:32:18

给分类(Category)添加属性的相关文章

为什么分类不能添加属性?

在分类里使用@property声明属性,只是将该属性添加到该类的属性列表,并声明了setter和getter方法,但是没有生成相应的成员变量,也没有实现setter和getter方法.并且这里用点语法会报错,所以说分类不能添加属性.但是在分类里使用@property声明属性后,又实现了setter和getter方法,那么在这个类以外可以正常通过点语法给该属性赋值和取值.就是说,在分类里使用@property声明属性,又实现了setter和getter方法后,可以认为给这个类添加上了属性.来源:h

iOS runtime探究(四): 从runtiem开始实践Category添加属性与黑魔法method swizzling

你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639335 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属

给category添加属性的方法

默认类别时无法添加属性的,但可以动态添加,利用runtime机制 #import static const void * externVariableKey =&externVariableKey; @implementation NSObject (Category) @dynamic variable: - (id) variable { return objc_getAssociatedObject(self, externVariableKey); } - (void)setVariab

iOS在一个分类中添加属性

有时候,我们会想在别人的类中添加一个属性.这个属性只会在自己的模块用到,在其它地方无用.那么现在就用两个方案: 1,直接在原类中添加一个属性 2,写一个分类,在分类中将这个属性加进去. 这两种方案实现的异同: 同:都能达到在已有的类中添加一个属性的需求. 异: 第一种方案优点:实现简单.缺点:破坏了已有的类的封装,会给后续开发者带来疑惑.结论:笨方法 第二种方案有点:能与已有类完全分开,保持了模块化的独立性.貌似没有缺点,如果一定要找出一个缺点,那就是一个字"难",因为要用到个高大上的

iOS动态性:动态添加属性的方法——关联(e.g. 向Category添加属性)

想到要如何为所有的对象增加实例变量吗?我们知道,使用Category可以很方便地为现有的类增加方法,但却无法直接增加实例变量.不过从Mac OS X v10.6开始,系统提供了Associative References,这个问题就很容易解决了.这种方法也就是所谓的关联(association),我们可以在runtime期间动态地添加任意多的属性,并且随时读取.所用到的两个重要runtime API是: 1 OBJC_EXPORT void objc_setAssociatedObject(id

通过运行时动态给分类添加属性

#import <UIKit/UIKit.h> /** iOS 开发中,分类默认不允许保存属性 如果在分类中,定义一个属性,需要自己实现 getter & setter 方法,而且没有 _成员变量 如果在自己开发的框架中,希望在分类中动态添加属性,可以通过 OC 运行时的关联对象的功能! 运行时非常重要的一个应用:给分类动态添加属性,结果能够让框架包装的更好,让使用者做出最小的修改! */ @interface UIImageView (WebImage) @property (non

Objective-C 给分类添加“属性”——关联对象

给分类添加"属性" 咱们知道,分类中可以添加方法,却无法添加属性.那咱们有其他的方法来实现吗? 先来看看下面这段代码: @interface UIView (nl_Frame) @property (nonatomic, assign) CGFloat nl_width; @end @implementation UIView (nl_Frame) - (void)setNl_width:(CGFloat)nl_width { CGRect frame = self.frame; fr

快速上手Runtime(二)之给分类添加属性

我们都知道,分类是不能直接添加属性的,那么我们有时候又需要实现这个功能,那么我们应该怎么办才能为分类添加上属性呢. Runtime给分类添加属性原理 给一个类声明属性,其实本质就是给这个类添加关联,并不是直接把这个值的内存空间添加到类存空间. Runtime给分类添加属性步骤 1.在分类的.h文件中声明想要定义的属性 2.在分类的.m文件中实现getter和setter方法 3.引入runtime头文件,然后在setter方法中用objc_setAssociatedObject关联对象 比如给N

category中添加属性的简单方式

一.概念扩充: 1.如我们所知,使用category是用来对现有类进行功能扩展,或者将类分成多模块的一种方式.由声明和实现两部分组成.可以单独写成Objiective-C File类型文件(包含.h和.m). 2.category可以用来给现有类添加新的方法. 3.category不可以给类添加成员,会直接报错(编译不过). 4.category可以用@property来添加属性,此种方式会自动生成对应属性的set和get方法的声明,但是没有set和get方法的实现,也不会自动生成带有“_”的属