// 因?yàn)閱渭兪菫榱朔乐贡罎⒄恍遥蕸]有.h文件
.m 代碼如下
#pragma mark - exchange method
void exchangeClassMethod(Class anClass,SEL method1Sel, SEL method2Sel)
{
Method method1 = class_getClassMethod(anClass, method1Sel);
Method method2 = class_getClassMethod(anClass, method2Sel);
method_exchangeImplementations(method1, method2);
}
void exchangeInstanceMethod(Class anClass,SEL method1Sel, SEL method2Sel)
{
Method originalMethod = class_getInstanceMethod(anClass, method1Sel);
Method swizzledMethod = class_getInstanceMethod(anClass, method2Sel);
BOOL didAddMethod =
class_addMethod(anClass,
method1Sel,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(anClass,
method2Sel,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
}
else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
@implementation NSNull (Safe)
#pragma mark - safe for string
/**
* null string is not equal to any tring
*/
- (BOOL)isEqualToString:(NSString *)aString
{
return NO;
}
/**
* for this method
* [NSString stringWithFormat:@"%@",[NSNull null]]
* not return @"(null)" but @""
*/
- (NSString *)description
{
return @"";
}
#pragma mark - number or string change to c number
- (NSInteger)integerValue
{
return 0;
}
- (NSUInteger)unsignedIntegerValue
{
return 0;
}
- (int)intValue
{
return 0;
}
- (unsigned int)unsignedIntValue
{
return 0;
}
- (long)longValue
{
return 0;
}
- (unsigned long)unsignedLongValue
{
return 0;
}
- (long long)longLongValue
{
return 0;
}
- (unsigned long long)unsignedLongLongValue
{
return 0;
}
- (float)floatValue
{
return 0;
}
- (double)doubleValue
{
return 0;
}
- (BOOL)boolValue
{
return NO;
}
#pragma mark - safe for number
- (BOOL)isEqualToNumber:(NSNumber *)number
{
return NO;
}
@end
@implementation NSString (Safe)
- (id)forwardingTargetForSelector:(SEL)aSelector
{
if ([NSNumber resolveInstanceMethod:aSelector]) {
return [NSDecimalNumber decimalNumberWithString:self];
}
return self;
}
@end
@implementation NSDictionary (Safe)
+ (void)load
{
exchangeClassMethod(self, @selector(dictionaryWithObjects:forKeys:count:), @selector(avoidCrashDictionaryWithObjects:forKeys:count:));
}
+ (instancetype)avoidCrashDictionaryWithObjects:(const id _Nonnull __unsafe_unretained *)objects forKeys:(const id<NSCopying> _Nonnull __unsafe_unretained *)keys count:(NSUInteger)cnt {
id instance = nil;
@try {
instance = [self avoidCrashDictionaryWithObjects:objects forKeys:keys count:cnt];
}
@catch (NSException *exception) {
NSUInteger index = 0;
id _Nonnull __unsafe_unretained newObjects[cnt];
id _Nonnull __unsafe_unretained newkeys[cnt];
for (int i = 0; i < cnt; i++) {
if (objects[i] && keys[i]) {
newObjects[index] = objects[i];
newkeys[index] = keys[i];
index++;
}
}
instance = [self avoidCrashDictionaryWithObjects:newObjects forKeys:newkeys count:index];
}
@finally {
return instance;
}
}
@end
@implementation NSArray (Safe)
+ (void)load
{
exchangeClassMethod([self class], @selector(arrayWithObjects:count:), @selector(AvoidCrashArrayWithObjects:count:));
Class __NSArray = NSClassFromString(@"NSArray");
Class __NSArrayI = NSClassFromString(@"__NSArrayI");
Class __NSSingleObjectArrayI = NSClassFromString(@"__NSSingleObjectArrayI");
Class __NSArray0 = NSClassFromString(@"__NSArray0");
exchangeInstanceMethod(__NSArray, @selector(objectsAtIndexes:), @selector(avoidCrashObjectsAtIndexes:));
exchangeInstanceMethod(__NSArrayI, @selector(objectAtIndex:), @selector(__NSArrayIAvoidCrashObjectAtIndex:));
exchangeInstanceMethod(__NSSingleObjectArrayI, @selector(objectAtIndex:), @selector(__NSSingleObjectArrayIAvoidCrashObjectAtIndex:));
exchangeInstanceMethod(__NSArray0, @selector(objectAtIndex:), @selector(__NSArray0AvoidCrashObjectAtIndex:));
}
+ (instancetype)AvoidCrashArrayWithObjects:(const id _Nonnull __unsafe_unretained *)objects count:(NSUInteger)cnt {
id instance = nil;
@try {
instance = [self AvoidCrashArrayWithObjects:objects count:cnt];
}
@catch (NSException *exception) {
NSInteger newObjsIndex = 0;
id _Nonnull __unsafe_unretained newObjects[cnt];
for (int i = 0; i < cnt; i++) {
if (objects[i] != nil) {
newObjects[newObjsIndex] = objects[i];
newObjsIndex++;
}
}
instance = [self AvoidCrashArrayWithObjects:newObjects count:newObjsIndex];
}
@finally {
return instance;
}
}
- (NSArray *)avoidCrashObjectsAtIndexes:(NSIndexSet *)indexes {
NSArray *returnArray = nil;
@try {
returnArray = [self avoidCrashObjectsAtIndexes:indexes];
} @catch (NSException *exception) {
} @finally {
return returnArray;
}
}
- (id)__NSArrayIAvoidCrashObjectAtIndex:(NSUInteger)index {
id object = nil;
@try {
object = [self __NSArrayIAvoidCrashObjectAtIndex:index];
}
@catch (NSException *exception) {
}
@finally {
return object;
}
}
- (id)__NSArray0AvoidCrashObjectAtIndex:(NSUInteger)index {
id object = nil;
@try {
object = [self __NSArray0AvoidCrashObjectAtIndex:index];
}
@catch (NSException *exception) {
}
@finally {
return object;
}
}
- (id)__NSSingleObjectArrayIAvoidCrashObjectAtIndex:(NSUInteger)index {
id object = nil;
@try {
object = [self __NSSingleObjectArrayIAvoidCrashObjectAtIndex:index];
}
@catch (NSException *exception) {
}
@finally {
return object;
}
}
@end