...
|
...
|
@@ -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];
|
|
|
}
|
|
|
}
|
|
|
|
...
|
...
|
|