1. 程式人生 > >runtime 實際應用匯總

runtime 實際應用匯總

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];
    }
}