關(guān)于runtime的運用有:
1 消息傳遞(調(diào)用方法): objc_msgSend
2 動態(tài)添加方法 : class_addMethod
3 交換方法(Method Swizzling)
4 動態(tài)添加屬性(在分類中添加屬性,以及獲取私有屬性或成員變量_ivar)
5 NSCoding自動歸檔解檔
(場景:如果一個模型有許多個屬性族扰,實現(xiàn)自定義模型數(shù)據(jù)持久化時,需要對每一個屬性都實現(xiàn)一遍encodeObject 和 decodeObjectForKey方法,比較麻煩渔呵。我們就可以使用Runtime獲取屬性列表遍歷屬性來解決怒竿。
原理:用runtime提供的函數(shù)遍歷Model自身所有屬性,并對屬性進(jìn)行encode和decode操作扩氢。)
6 字典轉(zhuǎn)模型(原理同上)
7 熱更新 比如jspatch 基礎(chǔ)原理是OC的動態(tài)語言特性
OC的消息機(jī)制消息發(fā)送耕驰,動態(tài)解析,消息轉(zhuǎn)發(fā)录豺。就是在消息轉(zhuǎn)發(fā)階段動態(tài)的添加了方法的實現(xiàn)朦肘,以達(dá)到熱修復(fù)的目的。
8 制作插件
objc_msgSend應(yīng)用場景
- 創(chuàng)建并初始化對象
- 發(fā)送無參數(shù)無返回值的消息
- 發(fā)送有參數(shù)無返回值的消息
- 發(fā)送有參數(shù)有返回值",
- 帶浮點返回值的消息"
//注意??
#import <objc/runtime.h>
#import <objc/message.h>
創(chuàng)建并初始化對象
//1.創(chuàng)建對象在執(zhí)行Person *p = [[Person alloc]init]時双饥,會轉(zhuǎn)換成以下代碼
Person *person = ((Person * (*)(id, SEL))objc_msgSend)((id)[Person class], @selector(alloc));
//2.初始化對象
p = ((Person * (*)(id,SEL))objc_msgSend)((id)person, @selector(init));
發(fā)送無參數(shù)無返回值的消息
- (void)action_method1{
((void (*)(id,SEL))objc_msgSend)(self,@selector(action_test1));
}
- (void)action_test1{
NSLog(@"執(zhí)行了");
}
發(fā)送有參數(shù)無返回值的消息
- (void)action_method2{
NSString *str = @"喵喵桑愛妙鮮包";
((void (*)(id, SEL, NSString *))objc_msgSend)(self, @selector(action_test2:),str);
}
- (void)action_test2:(id)info{
NSLog(@"吃了小孩");
}
發(fā)送有參數(shù)有返回值的消息
- (void)action_method3{
NSString *str = @"以前的字符串";
str = ((id (*)(id, SEL, NSString *))objc_msgSend)(self, @selector(action_test3:),str);
NSLog(@"str = %@",str);
}
- (id)action_test3:(id)info{
return @"獲得新的字符串";
}
發(fā)送帶有浮點類型的消息 (可以用objc_msgSend_fpret)
- (void)action_method4{
float price = ((float (*)(id, SEL))objc_msgSend_fpret)(self, @selector(action_test4));
NSLog(@"價格price = %f",price);
}
- (float)action_test4{
return 100.5;
}
發(fā)送帶有結(jié)構(gòu)體返回值的消息
- (void)action_method5{
CGRect frame = ((CGRect (*)(id, SEL))objc_msgSend_stret)(self, @selector(action_test5));
NSLog(@"frame = %@", NSStringFromCGRect(frame));
}
- (CGRect)action_test5{
return CGRectMake(15, 0, 200, 100);
}