【知识总结】category探索 — 如何在分类中添加一个属性(runtime)

添加属性的本质:

对象添加属性,并不是在对象中为属性分配响应的内存,而是通过一个指针指向这个属性,本质就是关联这个属性
因此,在分类中我们可以通过关联的方式添加属性


我们新建一个 UIView 的分类,在分类中添加属性和方法

@interface UIView (Extension)
@property (nonatomic, strong) NSString *property;
- (void)show;
@end

在 m 文件中实现 show 方法

#import "UIView+Extension.h"
@implementation UIView (Extension)
- (void)show
{
NSLog(@"%@", self.property);
}

@end

下面,我们来测试一下,在viewController中使用我们的分类

- (void)viewDidLoad {
[super viewDidLoad];

UIView *view = [[UIView alloc] init];
view.property = @"我是分类中添加的属性";
[view show];
}

运行,可以看到程序奔溃了,查看奔溃信息:

奔溃信息提示,我们的 分类中添加的属性, setProperty:方法没有实现

接下来,我们尝试实现setProperty:方法,但是会遇到下面的问题

系统提示我们使用 @dynamic 实现分类这个分类

接着,我们尝试使用 @dynamic 实现,如下:

上面,我们一直才尝试实现 setProperty: 方法,但是由于分类的特殊性
在分类中声明@property,只会生成方法的声明,不会生成方法的实现和带有_下划线的成员变量
而且我们尽量去尝试自己实现,系统也是不允许我们这么做的

于是我们使用runtime来实现为分类添加属性这一需求


使用到运行时,首先我们要导入 <objc/runtime.h> 头文件

#import "UIView+Extension.h"
#import <objc/runtime.h>

@implementation UIView (Extension)

- (void)setProperty:(NSString *)property
{
NSLog(@"实现 setProperty 方法");
objc_setAssociatedObject(self, @selector(property), property, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (NSObject *)property {

return objc_getAssociatedObject(self, @selector(property));

}

- (void)show
{
NSLog(@"show:%@", self.property);
}
@end

运行程序,查看结果

我们已经成功的为分类添加了一个属性

分析上面用到的两个运行时方法

void objc_setAssociatedObject(id object, const voidvoid *key, id value, objc_AssociationPolicy policy)

id objc_getAssociatedObject(id object, const voidvoid *key)

void objc_removeAssociatedObjects(id object)

把一个value关联到另外一个object里,类似NSDictionary的 setValue:forKey 。
用 objc_setAssociatedObject 关联以后,用 objc_getAssociatedObject 取出使用。
objc_AssociationPolicy 属性 是设定该value在object内的属性,即 assgin, (retain,nonatomic)...等

1. //policy
2. enum {
3. OBJC_ASSOCIATION_ASSIGN = 0, /**< Specifies a weak reference to the associated object. */
4. OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object.
5. * The association is not made atomically. */
6. OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /**< Specifies that the associated object is copied.
7. * The association is not made atomically. */
8. OBJC_ASSOCIATION_RETAIN = 01401, /**< Specifies a strong reference to the associated object.
9. * The association is made atomically. */
10. OBJC_ASSOCIATION_COPY = 01403 /**< Specifies that the associated object is copied.
11. * The association is made atomically. */
12. };
13.
14. /// Type to specify the behavior of an association.
15. typedef uintptr_t objc_AssociationPolicy;

我们可以通过这个运行方法,实现 button 事件的 block 实现

相关资料:
用objc/runtime给类别扩展属性 http://www.jianshu.com/p/84de8a931adf
objc_setAssociatedObject与Block的简单使用 http://www.jianshu.com/p/35df1ba1f107


有一个推荐添加读写属性的方法,如下

Paste_Image.png

这种方法的缺陷是,分类的实现不能独立实现在一个分类文件中,必须实现在同一个文件中,局限性就很大了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的...
    西木阅读 30,723评论 33 466
  • 对于从事 iOS 开发人员来说,所有的人都会答出【runtime 是运行时】什么情况下用runtime?大部分人能...
    梦夜繁星阅读 9,090评论 7 64
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 5,865评论 0 9
  • objc_getAssociatedObject返回与给定键的特定对象关联的值。ID objc_getAssoci...
    有一种再见叫青春阅读 5,579评论 0 7
  • 文\伏枥老马 在中国,因为喝酒而引起的人身伤亡事件已不鲜见,由此引发的官司和赔偿也时常见诸报端。2016年9月,海...
    道讯阅读 4,320评论 0 4