runtime 實際應用匯總
阿新 • • 發佈:2019-01-08
1、列印每一個介面的資訊
擴充套件UIViewController,在load方法中交換viewwillAppear方法,在新方法中列印本類資訊。初次接手專案時,可以通過這個方法快速熟悉專案。
+(void)load
{
#ifdef DEBUG
Method method1 = class_getClassMethod(self, @selector(newViewwillAppear:));
Method method2 = class_getClassMethod(self, @selector(viewWillAppear:));
method_exchangeImplementations(method1, method2);
#endif
}
-(void)newViewwillAppear:(BOOL)animated
{
NSString *className = NSStringFromClass([self class]);
if([className hasPrefix:@"UI"]){//指定哪些viewController列印資訊
NSLog(@"self_class===%@",NSStringFromClass([self class]));
}
[self newViewwillAppear:YES];//這裡其實是呼叫viewwillAppear 這個方法
}
2、為一些系統方法新增額外引數
char *asso_key = "key1";
objc_setAssociatedObject(self, asso_key , @"1111", OBJC_ASSOCIATION_COPY);
NSString *value = objc_getAssociatedObject(self, key);//這裡就可以取得新增的額外引數
//斷開關聯,只要將關聯的值設成nil就可以了
objc_setAssociatedObject(self, asso_key , nil, OBJC_ASSOCIATION_COPY);
3、防止程式呼叫一個未實現的方法導致崩潰
程式呼叫一個未實現的方法時會呼叫
+(BOOL)resolveInstanceMethod:(SEL)sel{}
我們在這個方法裡可以做操作防止程式崩潰。
+(BOOL)resolveInstanceMethod:(SEL)sel
{
BOOL res = class_addMethod(self, sel, [NSObject instanceMethodForSelector:sel], "[email protected]:");//給程式動態的新增方法
BOOL res = class_addMethod(self, sel, (IMP)addMethod, "[email protected]:");//新增一個定義好的方法
// 第一個引數:給哪個類新增方法
// 第二個引數:新增方法的方法編號
// 第三個引數:新增方法的函式實現(函式地址)
// 第四個引數:函式的型別,(返回值+引數型別) v:void @:物件->self :表示SEL->_cmd
return res;
}
void addMethod(id self,SEL _cmd,NSString *str){}
4、獲取類中一些資訊列表
獲取類中的屬性列表
unsigned int count = 0;
objc_property_t *property = class_copyPropertyList([self class], &count);
for(int i=0;i<count;i++){
const char *name = property_getName(property[i]);
NSLog(@"property===%@",[NSString stringWithUTF8String:name]);
}
free(property);
獲取成員變數(私有變數)列表
Ivar *ivarList = class_copyIvarList([self class], &count);
for(int i=0;i<count;i++){
const char *ivar = ivar_getName(ivarList[i]);
NSLog(@"ivar===%@",[NSString stringWithUTF8String:ivar]);
}
free(ivarList);
獲取方法列表
Method *methodList = class_copyMethodList([self class], &count);
for(int i=0;i<count;i++){
SEL sel = method_getName(methodList[i]);
NSLog(@"method === %@",NSStringFromSelector(sel));
}
free(methodList);
獲取協議列表
__unsafe_unretained Protocol **protocolList = class_copyProtocolList([self class], &count);
for(NSInteger i=0;i<count;i++){
Protocol *protocol = protocolList[i];
const char * propocolName = protocol_getName(protocol);
NSLog(@"protocol === %@",[NSString stringWithUTF8String:propocolName]);
}
free(protocolList);
自動的歸檔解檔
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if(self){
//遍歷所有屬性,做解檔操作
unsigned int count;
Ivar *ivarList = class_copyIvarList([self class], &count);
for(int i=0;i<count;i++){
NSString *key = [NSString stringWithUTF8String:ivar_getName(ivarList[i])];
[self setValue:[aDecoder decodeObjectForKey:key] forKey:key];
}
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
unsigned int count;
Ivar *ivarList = class_copyIvarList([self class], &count);
for(int i=0;i<count;i++){
NSString *key = [NSString stringWithUTF8String:ivar_getName(ivarList[i])];
[aCoder encodeObject:[self valueForKey:key] forKey:key];
}
}