博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
动态解析实现@dynamic属性、动态添加属以及获取类的实例变量和属性
阅读量:5923 次
发布时间:2019-06-19

本文共 4391 字,大约阅读时间需要 14 分钟。

以动态解析来实现@dynamic属性

+ (BOOL)resolveInstanceMethod:(SEL)sel {    NSString *selectorString = NSStringFromSelector(sel);        // 获取方法的类型编码(type encoding)做铺垫    Method exchangeSetM = class_getInstanceMethod([self class], @selector(insteadSetMethod));    Method exchangeGetM = class_getInstanceMethod([self class], @selector(insteadGetMethod));        if ([selectorString hasPrefix:@"set"]) {        //  method_getTypeEncoding()获取方法的类型编码(type encoding)        class_addMethod(self, sel, class_getMethodImplementation(self, @selector(insteadSetMethod)), method_getTypeEncoding(exchangeSetM));     }else {        class_addMethod(self, sel, class_getMethodImplementation(self, @selector(insteadGetMethod)), method_getTypeEncoding(exchangeGetM));  // 获取方法的类型编码(type encoding)    }    return YES;}- (void)insteadSetMethod {    NSLog(@"调用了==== SET");}- (NSString *)insteadGetMethod {    NSString *string = @"调用了==== GET 0001";    return string;}复制代码

重写resolveInstanceMethod:方法,给找不到实现的方法添加set,get方法。

动态添加属性

动态加载一个属性,只需利用分类机制就OK了,先看代码:

.h 文件#import 
@interface UIControl (Button)@property (nonatomic, assign) NSInteger clickCount;@end.m 文件#import "UIControl+Button.h"#import
static const char *BtnClick_Key = "btn_clickkey";@implementation UIControl (Button)- (void)setClickCount:(NSInteger)clickCount { objc_setAssociatedObject(self, BtnClick_Key, @(clickCount), OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (NSInteger)clickCount { return [objc_getAssociatedObject(self, BtnClick_Key) integerValue];}@end调用:UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];button.clickCount = 4;复制代码

通过上面代码,就可以动态添加属性。

objc_setAssociatedObject() : set(源对象,key值,value值,属性关联策略)
objc_getAssociatedObject() : get(源对象,key值)

属性关联策略:

typedefOBJC_ENUM(uintptr_t, objc_AssociationPolicy){    // 第一个关联策略是基于基本类型的,也就是我们常用的assign 属性    OBJC_ASSOCIATION_ASSIGN = 0,     /**< Specifies a weak reference to the associated object. *///关联策略是基于对象类型的,如我们正常的是retain nonatomic (非原子操作)类型 ,retain : 保留一个引用指针,内存地址不修改,指向同一块内存地址    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,     /**< Specifies a strong reference to the associated object. * The association is not made atomically. *///这个相当于属性中对一些对象或者字符串进行的copy 这个是拷贝一个新对象,内存地址不在一起,还是使用的非原子类型,非原子类型我们也称之为线程不安全的操作,但是对于OC里面的数据操作,我们尽量避开原子操作,原子操作是线程安全的,会影响我们对数据的写入操作    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,     /**< Specifies that the associated object is copied. * The association is not made atomically. */// 简单的指针引用, retain 操作    OBJC_ASSOCIATION_RETAIN = 01401,     /**< Specifies a strong reference to the associated object. * The association is made atomically. *///把简单的对象拷贝到一个新的内存地址    OBJC_ASSOCIATION_COPY = 01403    /**< Specifies that the associated object is copied. * The association is made atomically. */};复制代码

获取对象的成员变量或属性

直接上代码

@protocol PersonDelegate 
- (void)setBackgroundWithColor1:(NSString *)string;@end@interface Person : NSObject@property (nonatomic, strong) NSString *name;@property (nonatomic, assign) NSInteger age;@property (nonatomic, assign) float weight;@property (nonatomic, copy) id
delegate;- (void)testOne;- (void)changeTestString:(NSString *)string;@end#import "Person.h"@interface Person () { NSString *_decr;}@property (nonatomic, strong) NSString *title;@property (nonatomic, strong) UIView *testView;@end@implementation Person@end复制代码

使用class_copyIvarList获取类的成员变量:

- (void)getInfoByIvar {    unsigned int outCount = 0;    Ivar *ivars = class_copyIvarList([Person class], &outCount);    NSLog(@"ByIvar: %d", outCount);    for (int i = 0; i < outCount; i ++) {        const char *name = ivar_getName(ivars[i]);        NSString *key = [NSString stringWithUTF8String:name];        NSLog(@"==== %@", key);    }    free(ivars);}复制代码

它返回的是一个Ivar的数组,这个数组里面包含了你要查看类的所有实例变量,但是不包括从父类继承过来的。如果你传入的类没有实例变量或者改classNil,那么该方法返回的就是NULLcount值也就变成了0。有一点需要注意:你必须使用free()方法将该数组释放。 然后就是通过for循环遍历,通过ivar_getName拿到ivarName。 以上便是对clas_copyIvarList的介绍。

使用class_copyPropertyList获取类的属性

- (void)getInfoByProperty {    unsigned int outCount = 0;    objc_property_t *property = class_copyPropertyList([Person class], &outCount);    NSLog(@"ByProperty: %d", outCount);    for (int i = 0; i < outCount; i ++) {        NSString *name = @(property_getName(property[i]));        NSString *attributes = @(property_getAttributes(property[i]));        NSLog(@"==== %@ --------- %@", name, attributes);    }    free(property);}复制代码

转载地址:http://lrivx.baihongyu.com/

你可能感兴趣的文章
python函数参数类型校验
查看>>
fail2ban 帮助postfix 过滤恶意IP
查看>>
Simple Proxy Server (Java)
查看>>
自动学习MAC地址
查看>>
Kafka消费的几种方式--low-level SimpleConsumer
查看>>
解决mysql数据库不能支持中文的问题
查看>>
VMware14虚拟机秘钥
查看>>
JVM -verbose参数详解
查看>>
CentOS LInux启动关闭和服务管理
查看>>
Eclipse中10个最有用的快捷键组合
查看>>
yum的使用
查看>>
修改Debian root密码
查看>>
解决华为交换机无法Telnet、SSH
查看>>
vsftpd功能介绍
查看>>
php新玩具:psysh
查看>>
编码字符集
查看>>
pycharm license activation
查看>>
Linux下查看进程和线程
查看>>
Linux 下的 ps -ef 命令详解
查看>>
我的友情链接
查看>>