介绍
- dynamicWebkit替换、
- 动态添加方法 + 动态交换方法 -> UIButton防止多次点击、
- 遍历变量 -> 隐藏键盘、
- 遍历属性 -> 获取属性名
- 遍历属性 -> 判断所有变量是否已经实例化
dynamicWebkit
Apple 从 iOS8 开始,推出了更新、优化更好的WKWebkit。这个库是UIWebView的继承者,在相同的浏览页面下,WKWebKit提供的WKWebView的内存占用率甚至可以只有UIWebView的1/10。可惜的是,我们很多时候为了保证用户的覆盖率,target iOS Version都是 iOS7。这时候我们就需要使用UIWebView来达到显示的目的。
那么问题来了,如何实现根据iOS版本来达到动态加载的目的呢?
参考 http://www.jianshu.com/p/3f71fb190fbe
感觉这更多是偏向于URL route的感觉,类似的还有:
http://www.jianshu.com/p/8b3a9155468d
步骤:
- 新建UIButton分类,在load方法中 使用自定义方法替换掉原先的 - (void)sendAction:(SEL)action to:(nullable id)target forEvent:(nullable UIEvent *)event方法
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | + (void)load {SEL originSEL = @selector(sendAction:to:forEvent:);
 SEL mySEL = @selector(my_sendAction:to:forEvent:);
 
 Method originM = class_getInstanceMethod([self class], originSEL);
 const char *typeEncodinds = method_getTypeEncoding(originM);
 
 Method newM = class_getInstanceMethod([self class], mySEL);
 IMP newIMP = method_getImplementation(newM);
 
 if (class_addMethod([self class], mySEL, newIMP, typeEncodinds)) {
 class_replaceMethod([self class], originSEL, newIMP, typeEncodinds);
 } else {
 method_exchangeImplementations(originM, newM);
 }
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 | - (void)my_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
 
 if ([self isKindOfClass:[UIButton class]]) {
 
 
 self.clickDurationTime = self.clickDurationTime == 0 ? defaultDuration : self.clickDurationTime;
 
 
 if (_isIgnoreEvent) {
 NSLog(@" 忽略按钮事件 ");
 return;
 } else if(self.clickDurationTime > 0) {
 NSLog(@"//2.2 不忽略按钮事件");
 
 
 _isIgnoreEvent = YES;
 
 
 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.clickDurationTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
 resetState();
 });
 
 
 [self my_sendAction:action to:target forEvent:event];
 }
 
 } else {
 [self my_sendAction:action to:target forEvent:event];
 }
 }
 
 | 
遍历变量 -> 隐藏键盘
在viewcontroller中有些操作需要隐藏原先的键盘
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | 
 
 
 
 +(void)resignTFandTV:(id)obj{
 
 unsigned int outCount = 0;
 Ivar *vars = class_copyIvarList([obj class], &outCount);
 for (int i = 0; i < outCount; i ++) {
 Ivar var = vars[i];
 const char *name = ivar_getName(var);
 NSString *key = [NSString stringWithUTF8String:name];
 
 id value = [obj valueForKey:key];
 
 if ([value isKindOfClass:[UITextField class]] || [value isKindOfClass:[UITextView class]]) {
 if([value canResignFirstResponder])
 [value resignFirstResponder];
 }
 }
 }
 
 | 
遍历属性 -> 获取属性名
一些简单的model 或者自定义 view ,可以获取属性名来实例化对应的属性
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 
 | 
 
 
 
 
 
 
 +(NSMutableArray<NSString*>*)getIvarNamesFrom:(id)obj specialCls:(Class)aClass{
 
 NSMutableArray<NSString*>* arr = [NSMutableArray arrayWithCapacity:0];
 
 unsigned int outCount = 0;
 objc_property_t *properties = class_copyPropertyList([obj class], &outCount);
 for (int i = 0; i < outCount; i ++) {
 objc_property_t property = properties[i];
 
 NSString* name = [self getProertyIvarName:property];
 NSString* type = [self getProertyTypeName:property];
 
 if(aClass){
 if(type){
 Class someClass = NSClassFromString(type);
 if(someClass && someClass == aClass ){
 if(name) [arr addObject:name];
 }
 }
 }
 else{
 if(name) [arr addObject:name];
 }
 
 }
 free(properties);
 
 return arr;
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 +(NSString*)getProertyIvarName:(objc_property_t)property{
 
 unsigned int count = 0;
 objc_property_attribute_t *attrbutes = property_copyAttributeList(property, &count);
 for (unsigned int j = 0; j < count; ++j) {
 objc_property_attribute_t attribute = attrbutes[j];
 
 const char *name = attribute.name;
 const char *value = attribute.value;
 NSString *utfName = [NSString stringWithUTF8String:name];
 NSString *utfValue = [NSString stringWithUTF8String:value];
 
 if([utfName isEqualToString:@"V"]){
 
 utfValue = [utfValue stringByReplacingOccurrencesOfString:@"\"" withString:@""];
 utfValue = [utfValue stringByReplacingOccurrencesOfString:@"@" withString:@""];
 return utfValue;
 }
 }
 
 free(attrbutes);
 
 return nil;
 }
 
 
 
 
 
 
 
 +(NSString*)getProertyTypeName:(objc_property_t)property{
 
 unsigned int count = 0;
 objc_property_attribute_t *attrbutes = property_copyAttributeList(property, &count);
 for (unsigned int j = 0; j < count; ++j) {
 objc_property_attribute_t attribute = attrbutes[j];
 
 const char *name = attribute.name;
 const char *value = attribute.value;
 NSString *utfName = [NSString stringWithUTF8String:name];
 NSString *utfValue = [NSString stringWithUTF8String:value];
 
 if([utfName isEqualToString:@"T"]){
 
 utfValue = [utfValue stringByReplacingOccurrencesOfString:@"\"" withString:@""];
 utfValue = [utfValue stringByReplacingOccurrencesOfString:@"@" withString:@""];
 return utfValue;
 }
 }
 
 free(attrbutes);
 
 return nil;
 }
 
 | 
遍历属性 -> 判断所有变量是否已经实例化
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | 
 
 
 
 
 
 
 +(BOOL)isIvarsVaildOf:(id)obj specialCls:(Class)aClass{
 NSMutableArray<NSString*>* ivarNames = [self getIvarNamesFrom:self specialCls:aClass];
 for(int i = 0 ; i < ivarNames.count; i++){
 NSString* key = ivarNames[i];
 id value = [obj valueForKey:key];
 if(!value) return false;
 }
 return true;
 
 }
 
 
 
 +(BOOL)isIvarAllVaildOf:(id)obj{
 return [self isIvarsVaildOf:obj specialCls:nil];
 
 }
 
 |