iOS程序猿程序员iOS Developer

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

2016-12-11  本文已影响93人  小苗晓雪

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

主 Bundle 栏

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 <Foundation/Foundation.h>

@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 <Foundation/Foundation.h>

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

@end

NSObject+Runtime.m 文件

#import "NSObject+Runtime.h"
#import <objc/runtime.h>
@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

热爱开源

上一篇下一篇

猜你喜欢

热点阅读