使用运行时机制向Category中添加属性
来源:互联网 发布:大型投资理财网站源码 编辑:程序博客网 时间:2024/06/05 14:36
简明扼要
前言
了解OC的都应该知道,在一般情况下,我们是不能向Category中添加属性的,只能添加方法,但有些情况向,我们确实需要向Category中添加属性,而且很多系统的API也有一些在Category添加属性的情况,例如我们属性的UITableView
的section
和row
属性,就是定义在一个名为NSIndexPath
的分类里的,如下
那这到底是怎么实现的呢?
iOS运行时机制简介
iOS运行时机制,简单来说,就是苹果给开发这提供的一套在运行时动态创建类、添加属性/方法(不止这些,还有一些其他功能)的API,它是一套纯C语言的API,使用相应的API就可以通过Category给一个原本存在的类添加属性。
实例
#import<Foundation/Foundation.h>
#import<objc/runtime.h>
@interfaceNSObject (CategoryWithProperty)/** * 要在Category中扩展的属性 */
@property (nonatomic,strong)NSObject *property;
@end@implementationNSObject (CategoryWithProperty)- (NSObject *)property { return objc_getAssociatedObject(self,@selector(property));}
- (void)setProperty:(NSObject *)value { objc_setAssociatedObject(self,@selector(property), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}@end
这样就可以在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
- 使用运行时机制向Category中添加属性
- 使用运行时机制向Category中添加属性
- iOS运行时初探-使用运行时机制向Category中添加属性
- iOS运行时初探-使用运行时机制向Category中添加属性
- iOS运行时-使用Runtime向Category中添加属性以及运行时介绍
- iOS 利用运行时机制给现有类添加属性
- iOS 运行时runtime应用之二--在category中使用运行时API给类添加属性
- 分类(Category) 中添加属性
- iOS中动态添加属性的方法——关联(e.g. 向Category添加成员变量)
- 用Category给类中添加属性
- iOS中OC给Category添加属性
- category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性
- category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性
- category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性
- category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性
- category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性
- category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性
- ios中运行时机制
- css3 box-sizing属性
- Hdu 5744 Keep On Movin【思维】
- iOS开发-自定义控件的方式及注意
- ffmpeg使用参数的中文说明
- SpringMVC给控制器添加自定义注解控制访问权限(未测试)
- 使用运行时机制向Category中添加属性
- HDU1754 I Hate It 线段树入门题复习
- css 行框和清理
- hdu5734 推公式 多校2.1
- String.format()补全长度字符串
- 处理数据量大的问题
- 关于链接mysql报MySQLSyntaxErrorException: Table ** doesn't exist的问题
- Flexible Box布局
- Android相关技术知识点