runtime
runtime 就是運(yùn)行時(shí)
C語言聲明了方法是一定要實(shí)現(xiàn)的,不然編譯的部分就會(huì)給報(bào)錯(cuò)。OC的方法聲明完調(diào)用后不進(jìn)行實(shí)現(xiàn),也是可以編譯過去的。但是運(yùn)行的時(shí)候才會(huì)給報(bào)錯(cuò)。
xcode將消息機(jī)制的代碼提示給關(guān)閉了,這里需要自己手動(dòng)去打開才可以有代碼提示。buildSetting -> msg -> enable strict checking of objc_msgSend calls -> no
OC的代碼,在底層會(huì)被轉(zhuǎn)化為消息發(fā)送。
[self walk];
在底層就會(huì)被更改為
objc_msgSend(self, @selector(walk));
KVC、KVO的底層都是使用了runtime,內(nèi)存檢測工具也是使用了runtime。
runtime的基本用法
self.persion = [Persion new];
self.persion.name = @"Tom";
- 使用runtime改變變量的值
// 實(shí)例變量個(gè)數(shù)
unsigned int count = 0;
// 獲取persion中的所有屬性變量
Ivar* ivar = class_copyIvarList([self.persion class], &count);
// 遍歷
for (int i = 0; i < count; i++) {
// 實(shí)例變量
Ivar var = ivar[i];
// 返回一個(gè)C字符串的變量名稱
const char* varName = ivar_getName(var);
// 轉(zhuǎn)換成NSString類型
NSString* name = [NSString stringWithUTF8String:varName];
if ([name isEqualToString:@"_name"]) {
object_setIvar(self.persion, var, @"Jerry");
break;
}
}
- 使用runtime交換方法
// 獲取實(shí)例方法
Method m1 = class_getInstanceMethod([self.persion class], @selector(firstMethod));
Method m2 = class_getInstanceMethod([self.persion class], @selector(secondMethod));
// 交換
method_exchangeImplementations(m1, m2);
- 使用runtime添加方法
/// 動(dòng)態(tài)添加方法
- (void) addMethod {
//v@:@ v -> void @ -> id : -> SEL @ -> mile
class_addMethod([self.persion class], @selector(run:), (IMP)runMethod, "v@:@");
}
void runMethod(id self, SEL _cmd, NSString* miles) {
NSLog(@"%@", miles);
}
測試添加的方法成功了沒有
if ([self.persion respondsToSelector:@selector(run:)]) {
[self.persion performSelector:@selector(run:) withObject:@"9 miles"];
} else {
NSLog(@"方法沒有找到");
}
- 使用runtime添加屬性
添加屬性需要加一個(gè)category
#import "Persion+mult.h"
#import <objc/runtime.h>
@implementation Persion (mult)
const char* name1 = "jom";
/// 動(dòng)態(tài)為分類擴(kuò)展屬性
- (void)setNick:(NSString *)nick {
objc_setAssociatedObject(self, &name1, nick, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString*) nick {
return objc_getAssociatedObject(self, &name1);
}
@end
調(diào)用
self.persion.nick = @"cat";
NSLog(@"%@", self.persion.nick);