在分类里面声明了一个属性相当于声明 setter / getter 方法,但是并没有存储实例变量。这个时候是不能用的,那如何在分类里添加属性的呢?
1.重写 setter 和 getter
2.通过 runtime,关联属性
代码很少,直接贴源码了。
//
// Person+Attribute.h
// 01-RuntimeSendMessage
//
// Created by Mac on 2019/10/31.
// Copyright © 2019 Mac. All rights reserved.
//
#import "Person.h"
@interface Person (Attribute)
@property(nonatomic, copy) NSString *name;
@end
//
// Person+Attribute.m
// 01-RuntimeSendMessage
//
// Created by Mac on 2019/10/31.
// Copyright © 2019 Mac. All rights reserved.
//
#import "Person+Attribute.h"
#import <objc/runtime.h>
@implementation Person (Attribute)
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_ASSIGN);
}
- (NSString *)name {
return objc_getAssociatedObject(self, "name");
}
@end
通过objc_setAssociatedObject
这个方法去设置。我们点开进去,看一下它的源码
/**
* Sets an associated value for a given object using a given key and association policy.
*
* @param object The source object for the association.
* @param key The key for the association.
* @param value The value to associate with the key key for object. Pass nil to clear an existing association.
* @param policy The policy for the association. For possible values, see “Associative Object Behaviors.”
*
* @see objc_setAssociatedObject
* @see objc_removeAssociatedObjects
*/
OBJC_EXPORT void
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
id _Nullable value, objc_AssociationPolicy policy)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0);
第一个参数它让我们传一个对象,第二个参数传一个 key,第三个传一个 value,第四个直接传它给的就好了。
把值设置了之后我们需要获取的话就需要objc_getAssociatedObject
这个方法,第一个参数也是一个对象,第二个参数是一个 value。它通过我们在 setName 方法设置时传的 key,去找相对应的 value,然后返回一个 value 给我们。
这个就是关联属性,通过它实现了在分类里添加属性。
网友评论