123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- //
- // 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
|