Runtime存在OC中的意義:
Objc是一門動態(tài)語言踩叭,它會把一些決定性的工作推遲到運行時裆赵,這就需要一個運行時系統(tǒng)來執(zhí)行編譯后的代碼阳谍。runtime是Object的核心。
運行時最總要的四個應用場景
1 關聯(lián)對象 最多給分類動態(tài)添加屬性佣耐,oc分類默認不能添加屬性,運行時能夠更好的的解藕唧龄,簡化調用方的使用
2 動態(tài)獲取類的屬性 用于字典轉模型
3 交叉方法 黑魔法 對系統(tǒng)方法不滿意自己寫一個方法替換系統(tǒng)方法(不要輕易使用)對版本的依賴性很強 兼砖,有可能現(xiàn)在能是,過一段時間就不能使用(AFN使用較多 )
達到的目的:(1)攔截系統(tǒng)方法 (2)最好是攔截完系統(tǒng)方法后再實現(xiàn)自己的需求后再次回到系統(tǒng)方法中
4 NSClassFromString 等(部分人認為)
可以參考文檔http://www.cocoachina.com/industry/20140527/8570.html
下面列舉運行時字典轉模型的列子
- 創(chuàng)建一個模型
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property(strong, nonatomic) NSString * name;
@property(strong, nonatomic) NSString * age;
@property(strong,nonatomic) NSString * height;
@property(strong,nonatomic) NSString * title;
@property(strong,nonatomic) NSArray * friends;
@end
#import "Person.h"
@implementation Person
// 作用 使模型能通過NLog打印出屬性值
-(NSString*)description
{
NSArray *key = @[@"name",@"age",@"height",@"title"];
return [self dictionaryWithValuesForKeys:key].description;
}
@end
2.創(chuàng)建Person的分類
#import "Person.h"
@interface Person (Runtime)
/*
給定一個數(shù)組 創(chuàng)建self對象
*/
+(instancetype)YL_ObjectDic:(NSDictionary *)dict;
/*
獲取屬性列表
返回 屬性數(shù)組
*/
+(NSArray*)YL_ObjectProperties;
@end
#import "Person+Runtime.h"
#import <objc/runtime.h>
@implementation Person (Runtime)
//所有字典轉模型框架的核心
+(instancetype)YL_ObjectDic:(NSDictionary *)dict
{
id object =[[self alloc] init];
// 獲取類所有的屬性
NSArray *prolist =[self YL_ObjectProperties];
//遍歷字典給每一個屬性賦值
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
// 屬性中存在這個key
if ([prolist containsObject:key]) {
// kvc 添加到字典
[object setValue:obj forKey:key];
}
}];
return object;
}
+(NSArray*)YL_ObjectProperties
{
// 運行時取得類的屬性數(shù)組
//Ivar: 成員變量
//method:成員變量
//propretty:屬性
//protocal:協(xié)議
/*
參數(shù)
1.要獲取的類
2.類屬性的個數(shù)指針
返回值:所有屬性的數(shù)組 c語言中數(shù)組的名字就指向第一個元素的地址
*/
NSMutableArray *returnarry =[[NSMutableArray alloc] init];
unsigned int count = 0;
objc_property_t *prolist = class_copyPropertyList([self class], &count);
NSLog(@"屬性的count:%d",count);
// 遍歷所有數(shù)組 從數(shù)組中取得所有的屬性
for (int i=0; i<count; i++) {
objc_property_t pro = prolist[i];
// 轉字符串
const char * proname = property_getName(pro);// 獲取屬性的名字
NSString *proStr =[NSString stringWithCString:proname encoding:NSUTF8StringEncoding];
const char * attributes = property_getAttributes(pro);//獲取屬性類型
NSString *proAttributes = [NSString stringWithCString:attributes encoding:NSUTF8StringEncoding];
// 字符串轉對應的立刻調用函數(shù)
/*
SEL _selector = NSSelectorFromString(proAttributes);
id retVal = [self performSelector:_selector];
*/
// 添加數(shù)組
[returnarry addObject:proStr];
}
// 注意 :c語言的_copy,teturn,creat 需要釋放
free(prolist);
return returnarry;
}
@end
3 字典轉模型調用
- (void)viewDidLoad {
[super viewDidLoad];
// 獲取person類屬性數(shù)組 => 拿到屬性數(shù)組 目的為了后面通過kvc賦值
NSArray *properties = [Person YL_ObjectProperties];
NSLog(@"%@",properties);
// 字典模型設置
Person *mode = [Person YL_ObjectDic:@{@"name":@"張三",
@"age":@"張三",
@"height":@19,
@"title":@"YL",
@"friends":@[@"韓韓",@"軍軍",@"強強"]
}];
NSLog(@"mode:%@",mode);
NSLog(@"Arr:%@",mode.friends);
}
交叉方法待續(xù)。讽挟。懒叛。。