iOS method swizz

1: 防止按钮在一定时间内重复响应默认1秒

 1 //
 2 //  UIButton+AvoidDoubleClick.h
 3 //  51WaywardShop
 4 //
 5 //  Created by jisa on 2018/9/30.
 6 //  Copyright © 2018年 Anyike. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 NS_ASSUME_NONNULL_BEGIN
12 
13 @interface UIButton (AvoidDoubleClick)
14 
15 /**
16  避免多次点击重复响应。设置时间间隔(默认0.5S)
17  */
18 @property (class, nonatomic, assign) NSTimeInterval intervalTime;
19 
20 /**
21  上一次点击的时间
22  */
23 @property (nonatomic, assign) NSTimeInterval clickTime;
24 @end
25 
26 NS_ASSUME_NONNULL_END
 1 //
 2 //  UIButton+AvoidDoubleClick.m
 3 //  51WaywardShop
 4 //
 5 //  Created by jisa on 2018/9/30.
 6 //  Copyright © 2018年 Anyike. All rights reserved.
 7 //  
 8 
 9 #import "UIButton+AvoidDoubleClick.h"
10 #import <objc/runtime.h>
11 
12 @implementation UIButton (AvoidDoubleClick)
13 
14 + (void)load {
15     static dispatch_once_t onceToken;
16     dispatch_once(&onceToken, ^{
17         UIButton.intervalTime = 1;
18         SEL systemSEL = @selector(sendAction:to:forEvent:);
19         Method systemMethod = class_getInstanceMethod([self class], systemSEL);
20         
21         SEL customSEL = @selector(FF_sendAction:target:event:);
22         Method customMethod = class_getInstanceMethod(self, customSEL);
23         /// 防止子类没有重载父类的方法,找不到消息接收的对象。故使用方法交换时,通常配合,方法的添加和替换使用。
24         BOOL addSuccess = class_addMethod(self, systemSEL, method_getImplementation(customMethod), method_getTypeEncoding(customMethod));
25         if (addSuccess) {
26             class_replaceMethod(self, customSEL, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
27         }else {
28             method_exchangeImplementations(systemMethod, customMethod);
29         }
30     });
31 }
32 
33 
34 #pragma mark -- method
35 - (void)FF_sendAction:(SEL)action target:(id)target event:(UIEvent *)event {
36 
37     if (self.clickTime == 0) {
38         self.clickTime = [NSDate date].timeIntervalSince1970;
39         [self FF_sendAction:action target:target event:event];
40     }
41     if ([NSDate date].timeIntervalSince1970 - self.clickTime < UIButton.intervalTime) {
42         return;
43     }
44     if (UIButton.intervalTime > 0) {
45         self.clickTime = [NSDate date].timeIntervalSince1970;
46     }
47     [self FF_sendAction:action target:target event:event];
48 }
49 
50 
51 #pragma mark -- setter getter
52 + (void)setIntervalTime:(NSTimeInterval)intervalTime {
53     objc_setAssociatedObject(self, _cmd, @(intervalTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
54 }
55 
56 + (NSTimeInterval)intervalTime {
57     NSNumber *needNumber = objc_getAssociatedObject(self, @selector(setIntervalTime:));
58     return [needNumber integerValue];
59 }
60 
61 - (void)setClickTime:(NSTimeInterval)clickTime {
62     objc_setAssociatedObject(self, _cmd, @(clickTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
63 }
64 
65 - (NSTimeInterval)clickTime {
66     NSNumber *num = objc_getAssociatedObject(self, @selector(setClickTime:));
67     return [num integerValue];
68 }
69 @end

 

2: 防止数组下标越界。

    NSArray是一个抽象类。实际上使用的是“__NSArray0(空数组), __NSSingleObjectArrayI(只有一个元素的数组), __NSArrayI(超过两个元素的数组), __NSArrayM(可变数组)”。通过‘语法糖’获取元素时会走‘objectAtIndexedSubscript:’方法。

 1 //
 2 //  NSArray+Crash.h
 3 //  NetWork
 4 //
 5 //  Created by jisa on 2018/11/17.
 6 //  Copyright © 2018 jisa. All rights reserved.
 7 //  .h文件
 8 
 9 #import <Foundation/Foundation.h>
10 
11 NS_ASSUME_NONNULL_BEGIN
12 
13 @interface NSArray (Crash)
14 
15 @end
16 
17 NS_ASSUME_NONNULL_END
  1 //
  2 //  NSArray+Crash.m
  3 //  NetWork
  4 //
  5 //  Created by jisa on 2018/11/17.
  6 //  Copyright © 2018 jisa. All rights reserved.
  7 //  如果是一个空数组,即时'__NSArray0'时可以不用单独处理,会走'__NSSingleObjectArrayI'的方法。
  8 
  9 #import "NSArray+Crash.h"
 10 #import <objc/runtime.h>
 11 
 12 @implementation NSArray (Crash)
 13 + (void)load {
 14     
 15     /* 数组 元素1个 */
 16     SEL oriSingleSEL = @selector(objectAtIndex:);
 17     Method oriSingleMethod = class_getInstanceMethod(NSClassFromString(@"__NSSingleObjectArrayI"), oriSingleSEL);
 18     SEL autoSingleSEL = @selector(FF_SingleObjectAtIndex:);
 19     Method autoSingleMethod = class_getInstanceMethod(NSClassFromString(@"__NSSingleObjectArrayI"), autoSingleSEL);
 20     
 21     if (class_addMethod(self, oriSingleSEL, method_getImplementation(autoSingleMethod), method_getTypeEncoding(autoSingleMethod))) {
 22         class_replaceMethod(self, autoSingleSEL, method_getImplementation(oriSingleMethod), method_getTypeEncoding(oriSingleMethod));
 23     }else {
 24         method_exchangeImplementations(oriSingleMethod, autoSingleMethod);
 25     }
 26     
 27     /* 数组 语法糖 元素1个 */
 28     SEL oriSingleTangSEL = @selector(objectAtIndexedSubscript:);
 29     Method oriSingleTangMethod = class_getInstanceMethod(NSClassFromString(@"__NSSingleObjectArrayI"), oriSingleTangSEL);
 30     SEL autoSingleTangSEL = @selector(FF_SingleTangObjectAtIndex:);
 31     Method autoSingleTangMethod = class_getInstanceMethod(NSClassFromString(@"__NSSingleObjectArrayI"), autoSingleTangSEL);
 32     if (class_addMethod(self, oriSingleTangSEL, method_getImplementation(autoSingleTangMethod), method_getTypeEncoding(autoSingleTangMethod))) {
 33         class_replaceMethod(self, autoSingleTangSEL, method_getImplementation(oriSingleTangMethod), method_getTypeEncoding(oriSingleTangMethod));
 34     }else {
 35         method_exchangeImplementations(oriSingleTangMethod, autoSingleTangMethod);
 36     }
 37 
 38     
 39     /* 数组 元素超过2 */
 40     SEL oriSEL = @selector(objectAtIndex:);
 41     Method oriMethod = class_getInstanceMethod(NSClassFromString(@"__NSArrayI"), oriSEL);
 42     SEL autoSEL = @selector(FF_ObjectAtIndex:);
 43     Method autoMethod = class_getInstanceMethod(NSClassFromString(@"__NSArrayI"), autoSEL);
 44 
 45     if (class_addMethod(self, oriSEL, method_getImplementation(autoMethod), method_getTypeEncoding(oriMethod))) {
 46         class_replaceMethod(self, autoSEL, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod));
 47     }else {
 48         method_exchangeImplementations(oriMethod, autoMethod);
 49     }
 50     
 51     /* 数组 语法糖 元素超过2 */
 52     SEL oriTangSEL = @selector(objectAtIndexedSubscript:);
 53     Method oriTangMethod = class_getInstanceMethod(NSClassFromString(@"__NSArrayI"), oriTangSEL);
 54     SEL autoTangSEL = @selector(FF_ObjectAtIndexSubscript:);
 55     Method autoTangMethod = class_getInstanceMethod(NSClassFromString(@"__NSArrayI"), autoTangSEL);
 56     if (class_addMethod(self, oriTangSEL, method_getImplementation(autoTangMethod), method_getTypeEncoding(autoTangMethod))) {
 57         class_replaceMethod(self, autoTangSEL, method_getImplementation(oriTangMethod), method_getTypeEncoding(oriTangMethod));
 58     }else {
 59         method_exchangeImplementations(oriTangMethod, autoTangMethod);
 60     }
 61 
 62     /*   可变数组    */
 63     SEL oriMSEL = @selector(objectAtIndex:);
 64     Method oriMMethod = class_getInstanceMethod(NSClassFromString(@"__NSArrayM"), oriMSEL);
 65     SEL autoMSEL = @selector(FF_MutableObjectAtIndex:);
 66     Method autoMMethod = class_getInstanceMethod(NSClassFromString(@"__NSArrayM"), autoMSEL);
 67     
 68     if (class_addMethod(self, oriMSEL, method_getImplementation(autoMMethod), method_getTypeEncoding(autoMMethod))) {
 69         class_replaceMethod(self, autoMSEL, method_getImplementation(oriMMethod), method_getTypeEncoding(oriMMethod));
 70     }else {
 71         method_exchangeImplementations(oriMMethod, autoMMethod);
 72     }
 73     
 74     /*  可变数组语法糖   */
 75     SEL oriMTangSEL = @selector(objectAtIndexedSubscript:);
 76     Method oriMTangMethod = class_getInstanceMethod(NSClassFromString(@"__NSArrayM"), oriMTangSEL);
 77     SEL autoMTangSEL = @selector(FF_MutableObjectAtIndexSubscript:);
 78     Method autoMTangMethod = class_getInstanceMethod(NSClassFromString(@"__NSArrayM"), autoMTangSEL);
 79     if (class_addMethod(self, oriMTangSEL, method_getImplementation(autoMTangMethod), method_getTypeEncoding(autoMTangMethod))) {
 80         class_replaceMethod(self, autoMTangSEL, method_getImplementation(oriMTangMethod), method_getTypeEncoding(oriMTangMethod));
 81     }else {
 82         method_exchangeImplementations(oriMTangMethod, autoMTangMethod);
 83     }
 84 
 85     
 86 }
 87 
 88 #pragma mark -- method
 89 - (id)FF_SingleObjectAtIndex:(NSInteger)index {
 90     if (self.count - 1 < index || self.count == 0) {
 91         @try {
 92             return [self FF_SingleObjectAtIndex:index];
 93         } @catch (NSException *exception) {
 94             NSLog(@"%@", exception.reason);
 95             return nil;
 96         } @finally {
 97             NSLog(@"下标越界");
 98         }
 99     }else {
100         return [self FF_SingleObjectAtIndex:index];
101     }
102 }
103 
104 
105 - (id)FF_SingleTangObjectAtIndex:(NSInteger)index {
106     if (self.count - 1 < index || self.count == 0) {
107         @try {
108             return [self FF_SingleTangObjectAtIndex:index];
109         } @catch (NSException *exception) {
110             NSLog(@"%@", exception.reason);
111             return nil;
112         } @finally {
113             NSLog(@"下标越界");
114         }
115     }else {
116         return [self FF_SingleTangObjectAtIndex:index];
117     }
118 }
119 
120 
121 - (id)FF_ObjectAtIndex:(NSInteger)index {
122     if (self.count - 1 < index || self.count == 0) {
123         @try {
124             return [self FF_ObjectAtIndex:index];
125         } @catch (NSException *exception) {
126             NSLog(@"%@", exception.reason);
127             return nil;
128         } @finally {
129             NSLog(@"下标越界");
130         }
131     }else {
132         return [self FF_ObjectAtIndex:index];
133     }
134 }
135 
136 - (id)FF_ObjectAtIndexSubscript:(NSInteger)index {
137     if (self.count - 1 < index || self.count == 0) {
138         @try {
139             return [self FF_ObjectAtIndexSubscript:index];
140         } @catch (NSException *exception) {
141             NSLog(@"%@", exception.reason);
142             return nil;
143         } @finally {
144             NSLog(@"下标越界");
145         }
146     }else {
147         return [self FF_ObjectAtIndexSubscript:index];
148     }
149 }
150 
151 - (id)FF_MutableObjectAtIndex:(NSInteger)index {
152     if (self.count - 1 < index || self.count == 0 ) {
153         @try {
154             return [self FF_MutableObjectAtIndex:index];
155         } @catch (NSException *exception) {
156             NSLog(@"%@", exception.reason);
157             return nil;
158         } @finally {
159             NSLog(@"下标越界");
160         }
161     }else {
162         return [self FF_MutableObjectAtIndex:index];
163     }
164 }
165 
166 - (id)FF_MutableObjectAtIndexSubscript:(NSInteger)index {
167     if (self.count - 1 < index || self.count == 0 ) {
168         @try {
169             return [self FF_MutableObjectAtIndexSubscript:index];
170         } @catch (NSException *exception) {
171             NSLog(@"%@", exception.reason);
172             return nil;
173         } @finally {
174             NSLog(@"下标越界");
175         }
176     }else {
177         return [self FF_MutableObjectAtIndexSubscript:index];
178     }
179 }
180 
181 @end

 

posted @ 2018-11-17 14:58  jisa  阅读(484)  评论(0编辑  收藏  举报