如何通过 Runtime 获取对象的属性

Runtime 的应用场景:
关联对象:

  • (1).仿照 SDWebImage
    - <1>给分类动态添加属性;
    - <2>解耦;
    - <3>简化使用;

  • (2).动态获取类的属性:
    - <1>字典 -->模型;
    - <2>建立 NSObject 分类;
    - <3>1.class_copyPropertyList--> 获取 Person 类.h 文件中的几个属性;
    - <4>遍历数组,用的不是 for - in 而是 for 循环 ;
    - <5>获得 Person 类. h 文件中的几个属性的名称用 getName方法:property_getName(这里放的是:"属性列表的数组") ;具体代码中会有体现!!!
    - <6>与字典转模型过程一样,创建可变数组并把名字添加到这个可变数组中 ;
    - <7>释放数组: free(propertyList) ;否则会有内存问题!!!

主 Bundle 栏

如何通过 Runtime 获取对象的属性_第1张图片
Snip20161211_7.png

ViewController.m 文件

#import "ViewController.h"
#import "Person.h"  //继承自NSObject
#import "NSObject+Runtime.h"    //NSObject的分类
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //获取 Person 类的属性数组:
    NSArray *propertiesArray = [Person MD_objProperties] ;
    NSLog(@"%@" , propertiesArray) ;
}

@end

Person.h 文件

#import 

@interface Person : NSObject
/**
 *  姓名:
 */
@property (nonatomic, copy) NSString *name ;
/**
 *  年龄
 */
@property (nonatomic) NSInteger age ;

/**
 * title:
 */
@property (nonatomic, copy) NSString *title ;

/**
 *  高度:
 */
@property (nonatomic) double height ;

@end

Person.m 文件

#import "Person.h"

@implementation Person

//什么也没有~空的!!!

@end

NSObject+Runtime.h 文件(给 NSObject 创建的分类)

#import 

@interface NSObject (Runtime)
/**
 *  获取累的属性列表数组:
 *
 *  @return 累的属性列表数组
 */
//创建类方法,该类方法返回的数据类型为一个数组:
+ (NSArray *)MD_objProperties ;

@end

NSObject+Runtime.m 文件

#import "NSObject+Runtime.h"
#import 
@implementation NSObject (Runtime)

//该类方法返回的数据类型为包含一个字符串内容为: hello 的数组:
+ (NSArray *)MD_objProperties {
    
    //调用运行时 runtime 取得 Person 类的属性列表:
    //Ivar:成员变量:
//    class_copyIvarList(__unsafe_unretained Class cls, unsigned int *outCount)
    //Method:成员方法:
//    class_copyMethodList(__unsafe_unretained Class cls, unsigned int *outCount)
    //Property:属性:
//    class_copyPropertyList(__unsafe_unretained Class cls, unsigned int *outCount)
    //protocol: 协议:
//    class_copyProtocolList(__unsafe_unretained Class cls, unsigned int *outCount)
    
    /**
     *  参数:
     1.__unsafe_unretained Class cls :要获取的类 ;
     2.unsigned int *outCount :类属性的个数的指针 ;
     *
     3.返回值为:所有属性的数组 ;
     运行时 Runtime 是 C 语言的概念:
     在 C 语言中数组的名字就是指向数组中第一个元素的地址!
     */
    
    //数组的数量:
    unsigned int count = 0 ;
    
    objc_property_t *propertyList = class_copyPropertyList([self class], &count) ;
    
    NSLog(@"属性的数量:%@" , [self class]) ;
    NSLog(@"属性的数量:%d" , count) ;
    
    //创建可变数组:
    NSMutableArray *mArray = [NSMutableArray array] ;
    
    //遍历所有属性:
    for (unsigned int i = 0; i < count; i++) {
        
        //1.从数组中取得所有属性:
        //注意这里不要再加 * 号,点进会发现他是一个结构体指针!
        objc_property_t pty = propertyList[i] ;
        
        //2.获得属性的名称:
        //这是一个 C 语言的字符串:
        const char *cName = property_getName(pty) ;
        
//        NSLog(@"%s" , cName) ;
        
        //C 语言字符串转成 OC 字符串:
        //    NSUTF8StringEncoding = 4:
        NSString *ocString = [NSString stringWithCString:cName encoding:4] ;
        
//        NSLog(@"%@" , ocString) ;
        
        //将属性名称添加到数组:
        [mArray addObject:ocString] ;
        
    }
    
    //一定要释放数组:!!!!!!!!
    free(propertyList) ;
    
    return mArray.copy ;
    
}

@end

热爱开源

你可能感兴趣的:(如何通过 Runtime 获取对象的属性)