iOS Runtime应用

  • 打印成员变量
   // 成员变量的数量
    unsigned int count;
    Ivar *ivars = class_copyIvarList([Person class], &count);
    for (int i = 0; i < count; i++) {
        // 取出i位置的成员变量
        Ivar ivar = ivars[i];
        NSLog(@"%s %s", ivar_getName(ivar), ivar_getTypeEncoding(ivar));
    }
    free(ivars);

  • 字典转模型
+ (instancetype)yz_objectWithJson:(NSDictionary *)json {

    id obj = [[self alloc] init];
    
    unsigned int count;
    Ivar *ivars = class_copyIvarList(self, &count);
    for (int i = 0; i < count; i++) {
        // 取出i位置的成员变量
        Ivar ivar = ivars[i];
        NSMutableString *name = [NSMutableString stringWithUTF8String:ivar_getName(ivar)];
        [name deleteCharactersInRange:NSMakeRange(0, 1)];
        
        // 设值
        id value = json[name];
        if ([name isEqualToString:@"ID"]) {
            value = json[@"id"];
        }
        [obj setValue:value forKey:name];
    }
    free(ivars);
    
    return obj;
}

  • 拦截按钮的点击事件(大数据统计应用)
  • 方法替换,本质是对调了method_t里的IMP函数地址。
@implementation UIControl (Extension)

+ (void)initialize {

 static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    Method method1 = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
    Method method2 = class_getInstanceMethod(self, @selector(yz_sendAction:to:forEvent:));
    method_exchangeImplementations(method1, method2);
  });
}

- (void)yz_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
    NSLog(@"%@-%@-%@", self, target, NSStringFromSelector(action));
    
    // 调用系统原来的实现
    [self yz_sendAction:action to:target forEvent:event];
    if ([self isKindOfClass:[UIButton class]]) {
       // 拦截了所有按钮的事件

   }
}

  • 数组添加对象,自动判断是否为空
#import "NSMutableArray+Extension.h"
#import 

@implementation NSMutableArray (Extension)

+ (void)initialize {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 类簇:NSString、NSArray、NSDictionary,真实类型是其他类型
        Class cls = NSClassFromString(@"__NSArrayM");
        Method method1 = class_getInstanceMethod(cls, @selector(insertObject:atIndex:));
        Method method2 = class_getInstanceMethod(cls, @selector(yz_insertObject:atIndex:));
        method_exchangeImplementations(method1, method2);
    });
}

- (void)yz_insertObject:(id)anObject atIndex:(NSUInteger)index
{
    if (anObject == nil) return;
    
    [self yz_insertObject:anObject atIndex:index];
}

  • 字典Key的判空
#import "NSMutableDictionary+Extension.h"
#import 

@implementation NSMutableDictionary (Extension)

+ (void)initialize {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class cls = NSClassFromString(@"__NSDictionaryM");
        Method method1 = class_getInstanceMethod(cls, @selector(setObject:forKeyedSubscript:));
        Method method2 = class_getInstanceMethod(cls, @selector(yz_setObject:forKeyedSubscript:));
        method_exchangeImplementations(method1, method2);
        
        Class cls2 = NSClassFromString(@"__NSDictionaryI");
        Method method3 = class_getInstanceMethod(cls2, @selector(objectForKeyedSubscript:));
        Method method4 = class_getInstanceMethod(cls2, @selector(yz_objectForKeyedSubscript:));
        method_exchangeImplementations(method3, method4);
    });
}

- (void)yz_setObject:(id)obj forKeyedSubscript:(id)key {
    if (!key) return;
    
    [self yz_setObject:obj forKeyedSubscript:key];
}

- (id)yz_objectForKeyedSubscript:(id)key {
    if (!key) return nil;
    return [self yz_objectForKeyedSubscript:key];
}

你可能感兴趣的:(iOS Runtime应用)