// // NSString+AvoidCrash.m // https://github.com/chenfanfang/AvoidCrash // // Created by mac on 16/10/5. // Copyright © 2016年 chenfanfang. All rights reserved. // #import "NSString+AvoidCrash.h" #import "AvoidCrash.h" @implementation NSString (AvoidCrash) + (void)avoidCrashExchangeMethod { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class stringClass = NSClassFromString(@"__NSCFConstantString"); //characterAtIndex [AvoidCrash exchangeInstanceMethod:stringClass method1Sel:@selector(characterAtIndex:) method2Sel:@selector(avoidCrashCharacterAtIndex:)]; //substringFromIndex [AvoidCrash exchangeInstanceMethod:stringClass method1Sel:@selector(substringFromIndex:) method2Sel:@selector(avoidCrashSubstringFromIndex:)]; //substringToIndex [AvoidCrash exchangeInstanceMethod:stringClass method1Sel:@selector(substringToIndex:) method2Sel:@selector(avoidCrashSubstringToIndex:)]; //substringWithRange: [AvoidCrash exchangeInstanceMethod:stringClass method1Sel:@selector(substringWithRange:) method2Sel:@selector(avoidCrashSubstringWithRange:)]; //stringByReplacingOccurrencesOfString: [AvoidCrash exchangeInstanceMethod:stringClass method1Sel:@selector(stringByReplacingOccurrencesOfString:withString:) method2Sel:@selector(avoidCrashStringByReplacingOccurrencesOfString:withString:)]; //stringByReplacingOccurrencesOfString:withString:options:range: [AvoidCrash exchangeInstanceMethod:stringClass method1Sel:@selector(stringByReplacingOccurrencesOfString:withString:options:range:) method2Sel:@selector(avoidCrashStringByReplacingOccurrencesOfString:withString:options:range:)]; //stringByReplacingCharactersInRange:withString: [AvoidCrash exchangeInstanceMethod:stringClass method1Sel:@selector(stringByReplacingCharactersInRange:withString:) method2Sel:@selector(avoidCrashStringByReplacingCharactersInRange:withString:)]; }); } //================================================================= // characterAtIndex: //================================================================= #pragma mark - characterAtIndex: - (unichar)avoidCrashCharacterAtIndex:(NSUInteger)index { unichar characteristic; @try { characteristic = [self avoidCrashCharacterAtIndex:index]; } @catch (NSException *exception) { NSString *defaultToDo = @"AvoidCrash default is to return a without assign unichar."; [AvoidCrash noteErrorWithException:exception defaultToDo:defaultToDo]; } @finally { return characteristic; } } //================================================================= // substringFromIndex: //================================================================= #pragma mark - substringFromIndex: - (NSString *)avoidCrashSubstringFromIndex:(NSUInteger)from { NSString *subString = nil; @try { subString = [self avoidCrashSubstringFromIndex:from]; } @catch (NSException *exception) { NSString *defaultToDo = AvoidCrashDefaultReturnNil; [AvoidCrash noteErrorWithException:exception defaultToDo:defaultToDo]; subString = nil; } @finally { return subString; } } //================================================================= // substringToIndex //================================================================= #pragma mark - substringToIndex - (NSString *)avoidCrashSubstringToIndex:(NSUInteger)to { NSString *subString = nil; @try { subString = [self avoidCrashSubstringToIndex:to]; } @catch (NSException *exception) { NSString *defaultToDo = AvoidCrashDefaultReturnNil; [AvoidCrash noteErrorWithException:exception defaultToDo:defaultToDo]; subString = nil; } @finally { return subString; } } //================================================================= // substringWithRange: //================================================================= #pragma mark - substringWithRange: - (NSString *)avoidCrashSubstringWithRange:(NSRange)range { NSString *subString = nil; @try { subString = [self avoidCrashSubstringWithRange:range]; } @catch (NSException *exception) { NSString *defaultToDo = AvoidCrashDefaultReturnNil; [AvoidCrash noteErrorWithException:exception defaultToDo:defaultToDo]; subString = nil; } @finally { return subString; } } //================================================================= // stringByReplacingOccurrencesOfString: //================================================================= #pragma mark - stringByReplacingOccurrencesOfString: - (NSString *)avoidCrashStringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement { NSString *newStr = nil; @try { newStr = [self avoidCrashStringByReplacingOccurrencesOfString:target withString:replacement]; } @catch (NSException *exception) { NSString *defaultToDo = AvoidCrashDefaultReturnNil; [AvoidCrash noteErrorWithException:exception defaultToDo:defaultToDo]; newStr = nil; } @finally { return newStr; } } //================================================================= // stringByReplacingOccurrencesOfString:withString:options:range: //================================================================= #pragma mark - stringByReplacingOccurrencesOfString:withString:options:range: - (NSString *)avoidCrashStringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange { NSString *newStr = nil; @try { newStr = [self avoidCrashStringByReplacingOccurrencesOfString:target withString:replacement options:options range:searchRange]; } @catch (NSException *exception) { NSString *defaultToDo = AvoidCrashDefaultReturnNil; [AvoidCrash noteErrorWithException:exception defaultToDo:defaultToDo]; newStr = nil; } @finally { return newStr; } } //================================================================= // stringByReplacingCharactersInRange:withString: //================================================================= #pragma mark - stringByReplacingCharactersInRange:withString: - (NSString *)avoidCrashStringByReplacingCharactersInRange:(NSRange)range withString:(NSString *)replacement { NSString *newStr = nil; @try { newStr = [self avoidCrashStringByReplacingCharactersInRange:range withString:replacement]; } @catch (NSException *exception) { NSString *defaultToDo = AvoidCrashDefaultReturnNil; [AvoidCrash noteErrorWithException:exception defaultToDo:defaultToDo]; newStr = nil; } @finally { return newStr; } } /* 版权声明:本文为CSDN博主「wangruiIOS」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/wangrui13931182709/article/details/51423566 */ +(void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ SEL systemSel = @selector(containsString:); Method systemMethod = class_getInstanceMethod([self class], systemSel); //如果没有找到,说明不包含此方法,需要动态添加此方法 if (systemMethod == NULL) { SEL customSel = @selector(customContainsString:); Method customMethod = class_getInstanceMethod([self class], customSel); BOOL isAdd = class_addMethod(self, systemSel, method_getImplementation(customMethod), method_getTypeEncoding(customMethod)); if (!isAdd) { NSLog(@"%@ runtime add method 'customContainsString:' failed",NSStringFromClass([self class])); } } }); } -(BOOL)customContainsString:(NSString *)str { NSRange range = [self rangeOfString:str]; if (range.location < self.length && range.length > 0) { return YES; } return NO; } @end