iOS runtime实用案例

案例一:避免向一个数组中加入nil时导致崩溃
  • 交换方法实现swizzle(+load 和 dispatch_once_t 能有效保证安全);
  • 获取类的实例方法class_getInstanceMethod,对应获取类的类方法class_getClassMethod
+(void)load{
    [self swizzleMethod:@selector(addObject:) anotherMethod:@selector(safeAddObject:)];
}

+ (void)swizzleMethod:(SEL)oneSel anotherMethod:(SEL)anotherSel{
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
     Method oneMethod = class_getInstanceMethod(NSClassFromString(@"__NSArrayM"), oneself);//类的真名
     Method anotherMethod = class_getInstanceMethod(self, anotherSel);
     if (!oneMethod || !anotherMethod) return;
     method_exchangeImplementations(oneMethod, anotherMethod);
});
}

- (void)safeAddObject:(id)obj {
     if (obj != nil) {
          [self safeAddObject:obj];//不会导致递归
     } else {
          NSLog(@"数组不能加入nil object");
     }
}
@end

案例二:防止按钮重复点击
  • 关联属性Associated object
#import "UIControl+Safety.h"
#import <objc/runtime.h>
static const char kSafety_ignoreEventTime;//按钮点击的时间
static const char kSafety_acceptEventInterval;//按钮点击的时间间隔
@interface UIControl ()
@property (nonatomic, assign) NSTimeInterval safety_ignoreEventTime;
@end
@implementation UIControl (Safety)
+(void)load {
    [self swizzleMethod:@selector(sendAction:to:forEvent:) anotherMethod:@selector(safety_sendAction:to:forEvent:)];
}
+ (void)swizzleMethod:(SEL)oneSel anotherMethod:(SEL)anotherSel {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Method oneMethod = class_getInstanceMethod(self, oneSel);
        Method anotherMethod = class_getInstanceMethod(self, anotherSel);
        if (!oneMethod || !anotherMethod) return;
        method_exchangeImplementations(oneMethod, anotherMethod);
    });
}
- (void)safety_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
    if (NSDate.date.timeIntervalSince1970 - self.safety_ignoreEventTime < self.safety_acceptEventInterval) {
        return;
    }
    
    if (self.safety_acceptEventInterval > 0) {
        self.safety_ignoreEventTime = NSDate.date.timeIntervalSince1970;
    }
    [self safety_sendAction:action to:target forEvent:event];
}

#pragma mark property 关联属性
- (NSTimeInterval)safety_ignoreEventTime {
    return [objc_getAssociatedObject(self, &kSafety_ignoreEventTime) doubleValue];
}

- (void)setSafety_ignoreEventTime:(NSTimeInterval)safety_ignoreEventTime {
    objc_setAssociatedObject(self, &kSafety_ignoreEventTime, @(safety_ignoreEventTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSTimeInterval)safety_acceptEventInterval {
    return [objc_getAssociatedObject(self, &kSafety_acceptEventInterval) doubleValue];
}

- (void)setSafety_acceptEventInterval:(NSTimeInterval)safety_acceptEventInterval {
    objc_setAssociatedObject(self, &kSafety_acceptEventInterval, @(safety_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
案例三:字典转模型原理
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,837评论 0 9
  • 本文转载自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex阅读 808评论 0 1
  • 文中的实验代码我放在了这个项目中。 以下内容是我通过整理[这篇博客] (http://yulingtianxia....
    茗涙阅读 955评论 0 6
  • 转载:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麦子阅读 776评论 0 2
  • 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的...
    lylaut阅读 832评论 0 4