美文网首页
防止数组越界Crash示例

防止数组越界Crash示例

作者: 小米咸鱼 | 来源:发表于2021-11-10 20:58 被阅读0次
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface NSArray (PreventCrash)
    
    @end
    
    @interface NSMutableArray (PreventCrash)
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "NSArray+PreventCrash.h"
    #import <objc/runtime.h>
    
    @implementation NSArray (PreventCrash)
    
    + (void)load{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            //处理数组越界crash
            NSArray* classNameArray = @[@"__NSArrayI",@"__NSArrayM",@"__NSSingleObjectArrayI"];
            [classNameArray enumerateObjectsUsingBlock:^(NSString*  className, NSUInteger idx, BOOL * _Nonnull stop) {
                Method objectAtIndexedSubscript = class_getInstanceMethod(objc_getClass(className.UTF8String), @selector(objectAtIndexedSubscript:));
                
                NSString* swizzingSelName = [className stringByAppendingString:@"_swizzing_objectAtIndexedSubscript:"];
                SEL swizzingSEL = NSSelectorFromString(swizzingSelName);
                Method swizzingObjectAtIndexedSubscript = class_getInstanceMethod(self, swizzingSEL);
                
                
                BOOL addSuccess = class_addMethod(self, @selector(objectAtIndexedSubscript:), method_getImplementation(swizzingObjectAtIndexedSubscript), method_getTypeEncoding(swizzingObjectAtIndexedSubscript));
                if (addSuccess) {
                    class_replaceMethod(self, swizzingSEL, method_getImplementation(objectAtIndexedSubscript), method_getTypeEncoding(objectAtIndexedSubscript));
                }else{
                    method_exchangeImplementations(objectAtIndexedSubscript, swizzingObjectAtIndexedSubscript);
                }
            }];
            
        });
    }
    
    #pragma mark - 数组越界方法
    - (id)__NSArrayI_swizzing_objectAtIndexedSubscript:(NSUInteger)idx{
        if (idx < self.count) {
            return self[idx];
        }
        return nil;
    }
    
    - (id)__NSArrayM_swizzing_objectAtIndexedSubscript:(NSUInteger)idx{
        if (idx < self.count) {
            return self[idx];
        }
        return nil;
    }
    
    - (id)__NSSingleObjectArrayI_swizzing_objectAtIndexedSubscript:(NSUInteger)idx{
        if (idx < self.count) {
            return self[idx];
        }
        return nil;
    }
    
    @end
    
    
    @implementation NSMutableArray (PreventCrash)
    
    + (void)load{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            //处理数组add nil
            Class mutableArrayClass = objc_getClass(@"__NSArrayM".UTF8String);
            SEL mutableInsertSEL = @selector(insertObject:atIndex:);
            SEL swizzingMutableInsertSEL = @selector(__NSArrayM_insertObject:atIndex:);
    
            Method mutableInsertMethod = class_getInstanceMethod(mutableArrayClass, mutableInsertSEL);
            Method swizzingMutableInsertMethod = class_getInstanceMethod(self, swizzingMutableInsertSEL);
    
            BOOL success = class_addMethod(mutableArrayClass, mutableInsertSEL, method_getImplementation(swizzingMutableInsertMethod), method_getTypeEncoding(swizzingMutableInsertMethod));
            if (success) {
                class_addMethod(mutableArrayClass, swizzingMutableInsertSEL, method_getImplementation(mutableInsertMethod), method_getTypeEncoding(mutableInsertMethod));
            }else{
                method_exchangeImplementations(mutableInsertMethod, swizzingMutableInsertMethod);
            }
            
        });
    }
    
    #pragma mark - NSArrayM
    - (void)__NSArrayM_insertObject:(id)anObject atIndex:(NSUInteger)index{
        if (!anObject) return;
        [self __NSArrayM_insertObject:anObject atIndex:index];
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:防止数组越界Crash示例

          本文链接:https://www.haomeiwen.com/subject/gdvizltx.html