美文网首页iOS程序猿IOS
使用AssociatedObject在分类中添加属性

使用AssociatedObject在分类中添加属性

作者: 重驹 | 来源:发表于2018-11-29 12:01 被阅读15次

面试题

Q:分类中到底能否实现属性?
A:
·1.如果把属性理解为通过方法访问的实例变量,答案是不能,因为分类不能为类增加额外的实例变量。会提示黄色警告,使用的时候运行到这里会crash。
·2.如果属性只是一个存取方法,那么分类是可以实现属性的。

这篇文章主要讲的是使用runtime里面的AssociatedObject关联对象的方法来模拟『属性』的存取方法,也就是 objc_getAssociatedObject 以及 objc_setAssociatedObject两个方法 。

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

在使用这两个方法之前需要在分类里面导入#import <objc/runtime.h> 或者 #import <objc/message.h> //这两种都可以。
说一下每个参数的含义:

  • 第一个方法的两个参数:
1.源对象(self)
2.关联时用来标记是哪一个属性的key
  • 第二个方法的参数:
1.源对象(self)
2.关联时用来标记是哪一个属性的key
3.关联的对象
4.关联策略(OBJC_ASSOCIATION_RETAIN_NONATOMIC)

关联策略是个枚举值

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    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并且关联对象使用原子性
};
名称 对应的修饰词
objc_AssociationPolicy modifier
OBJC_ASSOCIATION_ASSIGN assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC nonatomic, strong
OBJC_ASSOCIATION_COPY_NONATOMIC nonatomic, copy
OBJC_ASSOCIATION_RETAIN atomic, strong
OBJC_ASSOCIATION_COPY atomic, copy

也就是你定义属性的时候给的修饰词,譬如:

@property(nonatomic, strong)UIView *loadView;

上面这个属性关联策略也就是 OBJC_ASSOCIATION_RETAIN_NONATOMIC

@property(nonatomic, copy)NSString *name;

关联策略也就是 OBJC_ASSOCIATION_COPY_NONATOMIC

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

static NSString *loadViewKey = @"loadViewKey"; //loadViewKey的key

@implementation UIView (lf)


-(void)setLoadView:(UIView *)loadView{
    objc_setAssociatedObject(self, &loadViewKey, loadView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIView *)loadView{
    return objc_getAssociatedObject(self, &loadViewKey);
}

@end

有时候我们也会看到有人用下面的写法

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

static NSString *nameKey = @"nameKey"; //name的key

@implementation UIView (lf)

-(NSString *)name{
    return objc_getAssociatedObject(self, _cmd);
}
-(void)setName:(NSString *)name{
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

@end

这里的 _cmd 代指当前方法的选择子,也就是 @selector(name)。第二句代码中出现 @selector(name),这里它就调用第一句代码了, @selector直接返回SEL,则获取到name的方法名,则为第一句代码返回的值.

相关文章

  • 使用AssociatedObject在分类中添加属性

    面试题 Q:分类中到底能否实现属性?A:·1.如果把属性理解为通过方法访问的实例变量,答案是不能,因为分类不能为类...

  • Runtime 之 使用场合及OC中的动态性

    Runtime的使用场合 利用关联对象(AssociatedObject)给分类添加属性 遍历类的所有成员变量(修...

  • 笔记 - Runtime(征服面试官)

    什么是runtime? 平时项目中有用过么? 一、利用关联对象(AssociatedObject)给分类添加属性 ...

  • Runtime知识点整理5应用

    主要用途 利用关联对象(AssociatedObject)给分类添加属性 遍历类的所有成员变量(修改textfie...

  • 分类-Category

    分类-Category 分类的功能 在OC中,我们可以使用分类为类添加方法,属性.也可以覆盖类原有的方法,自己添加...

  • 分类-Category

    分类-Category 分类的功能 在OC中,我们可以使用分类为类添加方法,属性.也可以覆盖类原有的方法,自己添加...

  • 关联对象底层原理探究

    通常我们会在分类中添加方法,而无法在在分类中添加属性,我们在分类中添加@property(nonatomic, c...

  • iOS runtime之关联对象AssociatedObject

    在分类中添加属性,使用对象关联来实现: 例子:创建一个label的分类 #import@interfaceUILa...

  • 07.Objective-C 关联对象

    问题 分类中可以添加属性吗? 整么才能使分类中的属性,像正常类的属性一样使用? 关联对象的本质 答案 分类中可以添...

  • runtime常见用法一(给分类添加属性)

    开发中,我们常常会给系统提供的类添加分类,在分类里面可以添加方法,以方便我们使用,但是很多人遇到想给分类添加属性的...

网友评论

    本文标题:使用AssociatedObject在分类中添加属性

    本文链接:https://www.haomeiwen.com/subject/gwjxcqtx.html