运行时 - 动态获取对象属性

Runtime 消息机制: 程序启动时,首先加载运行时,是OC的底层

应用场景:

 1. 关联对象            ->  (给分类动态添加属性时简单提到过一次)
 2. 交换方法            ->  (换肤时介绍过)
 3. 动态获取对象属性

前两种使用场景之前简单提到过,这里来说一下动态获取对象属性的使用场景

为了演示动态获取对象属性:

  1. 我定义了一个Person类,声明了两个属性" name 和 age ";
  2. 创建一个NSObject+Runtime分类,提供一个方法来获取类的属性列表
 + (NSArray *)js_objProperties;

3.在ViewController中导入Person类和NSObject+Runtime,使用分类方法实例化对象属性列表并打印结果

Person类中,只声明了两个属性:

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) NSInteger age;

@end

NSObject+Runtime中

.h

#import <Foundation/Foundation.h>

@interface NSObject (Runtime)

// 获取类的属性列表数组
+ (NSArray *)js_objProperties;

@end

.m中

#import "NSObject+Runtime.h"
#import <objc/runtime.h>

@implementation NSObject (Runtime)

+ (NSArray *)js_objProperties{
    
    /*
        class_copyIvarList(__unsafe_unretained Class cls, unsigned int *outCount)       成员变量
        class_copyMethodList(__unsafe_unretained Class cls, unsigned int *outCount)     方法
        class_copyPropertyList(__unsafe_unretained Class cls, unsigned int *outCount)   属性
        class_copyProtocolList(__unsafe_unretained Class cls, unsigned int *outCount)   协议
    */
    
    /*      调用运行时方法,取得类的属性列表
 
        返回值 : 所有属性的数组 (是一个C数组指针:C语言中数组的名字就是首元素的地址)
        参数 1 :  要获取的类
        参数 2 :  类属性的个数指针
     */
    unsigned int count = 0;
    objc_property_t *propertyList = class_copyPropertyList([self class], &count);
    
    // 用来存放所有属性的数组
    NSMutableArray *mArr = [NSMutableArray array];
    
    // 遍历所有属性
    for (unsigned int i = 0; i < count; i ++) {
        
        // 1. 从数组中取得所有属性
        objc_property_t property = propertyList[i];
        
        const char *cName = property_getName(property);
        
        NSString *propertyName = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
        
        [mArr addObject:propertyName];
        
    }
    
    // C语言中 retain/create/copy 都需要release, 可以option+click方法名,通过API描述中找到释放方法  ( 例如这里的提示: You must free the array with free().)
    free(propertyList);
    
    return mArr.copy;
}

@end

控制器中

#import "ViewController.h"
#import "Person.h"
#import "NSObject+Runtime.h"

@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSArray *properties = [Person js_objProperties];
    
    NSLog(@"%@",properties);
}
@end

这样就实现了动态获取对象属性

打印信息:

2016-08-11 12:03:50.053 动态获取对象属性[11372:900458] (
    name,
    age
)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容