网易 crash保护

1.

 

@implementation NSObject(WMUnselectorExceptionHandler)

+ (void)wmcd_defend_handleUnrecognizerSelectorException {
    [WMRuntimeUtil exchangeInstanceSEL:@selector(forwardingTargetForSelector:)
                     targetInstanceSEL:@selector(wmcd_defend_forwardingTargetForSelector:)
                                aClass:self];
}

- (id)wmcd_defend_forwardingTargetForSelector:(SEL)aSelector {
    if ([self wmcd_defend_shouldCatchUnselector] && ![self wmcd_defend_isInWMServiceStack]) {
        return [self wmcd_defend_objectForUnselector:aSelector];
    }
    return [self wmcd_defend_forwardingTargetForSelector:aSelector];
}

- (BOOL)wmcd_defend_shouldCatchUnselector {
    if([WMUnrecognizerSelectorExceptionHandler prefixArray].count == 0 && [WMUnrecognizerSelectorExceptionHandler classArray].count == 0) {
        return YES;
    }
    NSString *className = NSStringFromClass([self class]);
    __block BOOL needCatch = NO;
    [[WMUnrecognizerSelectorExceptionHandler prefixArray] enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSRange range = [className rangeOfString:obj];
        if(range.location == 0) {
            needCatch = YES;
            *stop = YES;
        }
    }];
    [[WMUnrecognizerSelectorExceptionHandler classArray] enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if([className isEqualToString:obj]) {
            needCatch =YES;
            *stop = YES;
        }
    }];
    return needCatch;
}

- (BOOL)wmcd_defend_isInWMServiceStack {
    NSArray *callStackSymbols = [NSThread callStackSymbols];
    BOOL result = NO;
    for (NSString *callStatck in callStackSymbols) {
        if ([callStatck rangeOfString:@"+[WMService"].location != NSNotFound) {
            result = YES;
            break;
        }
    }
    return result;
}

- (id)wmcd_defend_objectForUnselector:(SEL)aSelector {
    _WMDefendUnselectorObject *defendObj = [[_WMDefendUnselectorObject alloc] init];
    SEL swizzledSelector = @selector(wmcd_generalMethodForDefend);
    Method swizzleMethod = class_getInstanceMethod([_WMDefendUnselectorObject class], swizzledSelector);
    BOOL didAddMethod = class_addMethod([_WMDefendUnselectorObject class],
                                        aSelector,
                                        method_getImplementation(swizzleMethod),
                                        method_getTypeEncoding(swizzleMethod));
    NSString *log = [NSString stringWithFormat:@"self:%@, didAddMethod:%d, for unselector:%@", NSStringFromClass([self class]), didAddMethod, NSStringFromSelector(aSelector)];
    [WMCrashLogger addCrashLogWithMessage:log];
    return defendObj;
}

@end

 

 

 

https://github.com/iwm2017/WMCrashDefend

 

https://github.com/qiyer/QYCrashProtector

https://www.jianshu.com/p/02157577d4e7

 

2.apple ForwardInvocation

 

https://developer.apple.com/library/archive/navigation/

 

https://developer.apple.com/library/archive/samplecode/ForwardInvocation/Listings/main_m.html#//apple_ref/doc/uid/DTS40008833-main_m-DontLinkElementID_4

https://www.cnblogs.com/treejohn/p/3596531.html

 

3.

 

IMP是一个函数指针,指向相应的函数实现,函数一般会有2个默认参数:id类型的self和SEL类型的_cmd。平时我们之所以能在OC函数中调用self,也是因为函数中有隐藏起来了的self参数

https://www.jianshu.com/p/6dcb18161fbb

 

posted @ 2018-12-17 10:39  lianhuaren  阅读(137)  评论(0编辑  收藏  举报