Authored by 张文文

枚举位运算逻辑修改

... ... @@ -10,18 +10,13 @@
#import "YH_CrashCatchError.h"
typedef NS_ENUM(NSInteger, YHCrashProtectionType) {
/*开启全部保护*/
YHCrashProtectionTypeAll = 0,
/*UnrecognizedSelector保护*/
YHCrashProtectionTypeUnrecognizedSelector = 1<<0,
/*KVO保护*/
YHCrashProtectionTypeKVO = 1<<1,
/*Notification*/
YHCrashProtectionTypeNotification = 1<<2,
/*Timer保护*/
YHCrashProtectionTypeTimer = 1<<3,
/*Containers保护:包括NSArray、NSMutableArray、NSDictionary、NSMutableDictionary、NSString、NSMutableString*/
YHCrashProtectionTypeContainers = 1<<4
YHCrashProtectionTypeNone = 0,
YHCrashProtectionTypeUnrecognizedSelector = 1<<0, //UnrecognizedSelector保护
YHCrashProtectionTypeKVO = 1<<1, //KVO保护
YHCrashProtectionTypeNotification = 1<<2, //Notification保护
YHCrashProtectionTypeTimer = 1<<3, //Timer保护
YHCrashProtectionTypeContainers = 1<<4, //Containers保护
YHCrashProtectionTypeAll = 1<<5, //全部保护
};
@interface YH_CrashProtector : NSObject
... ...
... ... @@ -345,50 +345,39 @@ static NSString *const NSNotificationProtectorValue = @"YHNotificationProtectorV
}
+ (void)filterProtectionsOn:(YHCrashProtectionType)protectionType operation:(BOOL)openOperation {
IMP imp;
if (protectionType > (1<<4)) {
imp = class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingContainersMethods));
[self filterProtectionsOn:YHCrashProtectionTypeContainers protectionName:@"Containers" operation:openOperation imp:imp];
protectionType -= (1<<4) ;
if (protectionType == YHCrashProtectionTypeNone) {
return;
}
if (protectionType > (1<<3) && protectionType != YHCrashErrorTypeContainers) {
imp = class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingTimerMethod));
[self filterProtectionsOn:YHCrashProtectionTypeTimer protectionName:@"Timer" operation:openOperation imp:imp];
protectionType -= (1<<3) ;
if (protectionType & YHCrashProtectionTypeUnrecognizedSelector) {
[self filterProtectionsOn:YHCrashProtectionTypeUnrecognizedSelector protectionName:@"UnrecognizedSelector" operation:openOperation imp:class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingForwardingTargetForSelectorMethod))];
}
switch (protectionType) {
case YHCrashProtectionTypeUnrecognizedSelector:
imp = class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingForwardingTargetForSelectorMethod));
[self filterProtectionsOn:protectionType protectionName:@"UnrecognizedSelector" operation:openOperation imp:imp];
break;
case YHCrashProtectionTypeKVO:
imp = class_getMethodImplementation([NSObject class], @selector(addObserver:forKeyPath:options:context:));
[self filterProtectionsOn:protectionType protectionName:@"KVO" operation:openOperation imp:imp];
break;
case YHCrashProtectionTypeNotification:
imp = class_getMethodImplementation([NSNotificationCenter class], @selector(addObserver:selector:name:object:));
[self filterProtectionsOn:protectionType protectionName:@"Notification" operation:openOperation imp:imp];
break;
case YHCrashProtectionTypeTimer:
imp = class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingTimerMethod));
[self filterProtectionsOn:protectionType protectionName:@"Timer" operation:openOperation imp:imp];
break;
case YHCrashProtectionTypeContainers:
imp = class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingContainersMethods));
[self filterProtectionsOn:protectionType protectionName:@"Containers" operation:openOperation imp:imp];
break;
case YHCrashProtectionTypeAll:
[self filterProtectionsOn:YHCrashProtectionTypeUnrecognizedSelector protectionName:@"UnrecognizedSelector" operation:openOperation imp:class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingForwardingTargetForSelectorMethod))];
[self filterProtectionsOn:YHCrashProtectionTypeKVO protectionName:@"KVO" operation:openOperation imp:class_getMethodImplementation([NSObject class], @selector(addObserver:forKeyPath:options:context:))];
[self filterProtectionsOn:YHCrashProtectionTypeNotification protectionName:@"Notification" operation:openOperation imp:class_getMethodImplementation([NSNotificationCenter class], @selector(addObserver:selector:name:object:))];
[self filterProtectionsOn:YHCrashProtectionTypeTimer protectionName:@"Timer" operation:openOperation imp:class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingTimerMethod))];
[self filterProtectionsOn:YHCrashProtectionTypeContainers protectionName:@"Containers" operation:openOperation imp:class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingContainersMethods))];
if (protectionType & YHCrashProtectionTypeKVO) {
[self filterProtectionsOn:YHCrashProtectionTypeKVO protectionName:@"KVO" operation:openOperation imp:class_getMethodImplementation([NSObject class], @selector(addObserver:forKeyPath:options:context:))];
}
if (protectionType & YHCrashProtectionTypeNotification) {
[self filterProtectionsOn:YHCrashProtectionTypeNotification protectionName:@"Notification" operation:openOperation imp:class_getMethodImplementation([NSNotificationCenter class], @selector(addObserver:selector:name:object:))];
}
if (protectionType & YHCrashProtectionTypeTimer) {
[self filterProtectionsOn:YHCrashProtectionTypeTimer protectionName:@"Timer" operation:openOperation imp:class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingTimerMethod))];
}
if (protectionType & YHCrashProtectionTypeContainers) {
[self filterProtectionsOn:YHCrashProtectionTypeContainers protectionName:@"Containers" operation:openOperation imp:class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingContainersMethods))];
}
if (protectionType & YHCrashProtectionTypeAll) {
[self filterProtectionsOn:YHCrashProtectionTypeUnrecognizedSelector protectionName:@"UnrecognizedSelector" operation:openOperation imp:class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingForwardingTargetForSelectorMethod))];
[self filterProtectionsOn:YHCrashProtectionTypeKVO protectionName:@"KVO" operation:openOperation imp:class_getMethodImplementation([NSObject class], @selector(addObserver:forKeyPath:options:context:))];
[self filterProtectionsOn:YHCrashProtectionTypeNotification protectionName:@"Notification" operation:openOperation imp:class_getMethodImplementation([NSNotificationCenter class], @selector(addObserver:selector:name:object:))];
[self filterProtectionsOn:YHCrashProtectionTypeTimer protectionName:@"Timer" operation:openOperation imp:class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingTimerMethod))];
[self filterProtectionsOn:YHCrashProtectionTypeContainers protectionName:@"Containers" operation:openOperation imp:class_getMethodImplementation([YH_CrashProtector class], @selector(yh_mappingContainersMethods))];
}
}
+ (void)filterProtectionsOn:(YHCrashProtectionType)protectionType protectionName:(NSString *)protectionName operation:(BOOL)openOperation imp:(IMP)imp {
... ... @@ -437,98 +426,29 @@ static NSString *const NSNotificationProtectorValue = @"YHNotificationProtectorV
+ (void)openProtectionsOn:(YHCrashProtectionType)protectionType catchErrorHandler:(void(^_Nullable)(YH_CrashCatchError * _Nullable error))errorHandler {
_errorHandler = errorHandler;
if (protectionType > (1<<4)) {
[self exchangeMethodWithType:YHCrashProtectionTypeContainers];
protectionType -= (1<<4);
if (protectionType == YHCrashProtectionTypeNone) {
return;
}
if (protectionType > (1<<3) && protectionType != YHCrashProtectionTypeContainers) {
[self exchangeMethodWithType:YHCrashProtectionTypeTimer];
protectionType -= (1<<3) ;
if (protectionType & YHCrashProtectionTypeUnrecognizedSelector) {
[self swizzleUnrecoginzeTypeMethod];
}
switch ((long)protectionType) {
case YHCrashProtectionTypeUnrecognizedSelector:
case YHCrashProtectionTypeKVO:
case YHCrashProtectionTypeNotification:
case YHCrashProtectionTypeTimer:
case YHCrashProtectionTypeContainers:
case YHCrashProtectionTypeAll:
{
[self exchangeMethodWithType:protectionType];
}
break;
case 3:
{
[self exchangeMethodWithType:YHCrashProtectionTypeUnrecognizedSelector];
[self exchangeMethodWithType:YHCrashProtectionTypeKVO];
}
break;
case 5:
{
[self exchangeMethodWithType:YHCrashProtectionTypeUnrecognizedSelector];
[self exchangeMethodWithType:YHCrashProtectionTypeNotification];
}
break;
case 6:
{
[self exchangeMethodWithType:YHCrashProtectionTypeKVO];
[self exchangeMethodWithType:YHCrashProtectionTypeNotification];
}
break;
case 7:
{
[self exchangeMethodWithType:YHCrashProtectionTypeUnrecognizedSelector];
[self exchangeMethodWithType:YHCrashProtectionTypeKVO];
[self exchangeMethodWithType:YHCrashProtectionTypeNotification];
}
break;
if (protectionType & YHCrashProtectionTypeKVO) {
[self swizzleKVOTypeMethod];
}
}
+ (void)exchangeMethodWithType:(YHCrashProtectionType)protectionType {
switch (protectionType) {
case YHCrashProtectionTypeUnrecognizedSelector:
{
[self swizzleUnrecoginzeTypeMethod];
}
break;
case YHCrashProtectionTypeKVO:
{
[self swizzleKVOTypeMethod];
}
break;
case YHCrashProtectionTypeNotification:
{
[self swizzleNotificationTypeMethod];
}
break;
case YHCrashProtectionTypeTimer:
{
[self swizzleTimerTypeMethod];
}
break;
case YHCrashProtectionTypeContainers:
{
[self swizzleContainersTypeMethod];
}
break;
case YHCrashProtectionTypeAll:
{
[self swizzleUnrecoginzeTypeMethod];
[self swizzleKVOTypeMethod];
[self swizzleNotificationTypeMethod];
[self swizzleTimerTypeMethod];
[self swizzleContainersTypeMethod];
}
break;
if (protectionType & YHCrashProtectionTypeNotification) {
[self swizzleNotificationTypeMethod];
}
if (protectionType & YHCrashProtectionTypeTimer) {
[self swizzleTimerTypeMethod];
}
if (protectionType & YHCrashProtectionTypeContainers) {
[self swizzleContainersTypeMethod];
}
}
... ...