Runtime 消息機制: 程序啟動時,首先加載運行時,是OC的底層
應(yīng)用場景:
1. 關(guān)聯(lián)對象 -> (給分類動態(tài)添加屬性時簡單提到過一次)
2. 交換方法 -> (換膚時介紹過)
3. 動態(tài)獲取對象屬性
前兩種使用場景之前簡單提到過,這里來說一下動態(tài)獲取對象屬性的使用場景
為了演示動態(tài)獲取對象屬性:
- 我定義了一個Person類,聲明了兩個屬性" name 和 age ";
- 創(chuàng)建一個NSObject+Runtime分類,提供一個方法來獲取類的屬性列表
+ (NSArray *)js_objProperties;
3.在ViewController中導(dǎo)入Person類和NSObject+Runtime,使用分類方法實例化對象屬性列表并打印結(jié)果
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)
// 獲取類的屬性列表數(shù)組
+ (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) 協(xié)議
*/
/* 調(diào)用運行時方法,取得類的屬性列表
返回值 : 所有屬性的數(shù)組 (是一個C數(shù)組指針:C語言中數(shù)組的名字就是首元素的地址)
參數(shù) 1 : 要獲取的類
參數(shù) 2 : 類屬性的個數(shù)指針
*/
unsigned int count = 0;
objc_property_t *propertyList = class_copyPropertyList([self class], &count);
// 用來存放所有屬性的數(shù)組
NSMutableArray *mArr = [NSMutableArray array];
// 遍歷所有屬性
for (unsigned int i = 0; i < count; i ++) {
// 1. 從數(shù)組中取得所有屬性
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
這樣就實現(xiàn)了動態(tài)獲取對象屬性
打印信息:
2016-08-11 12:03:50.053 動態(tài)獲取對象屬性[11372:900458] (
name,
age
)