美文网首页iOS点点滴滴
runtime方法替换 array添加元素addObject运行

runtime方法替换 array添加元素addObject运行

作者: 番薯大佬 | 来源:发表于2018-07-07 07:56 被阅读10次

    通过方法转换,将array添加元素的方法进行转换,避免添加nil对象时出现crash情况。

    #import <Foundation/Foundation.h>
    
    @interface NSMutableArray (RunTime)
    
    @end
    
    #import "NSMutableArray+RunTime.h"
    #import <objc/runtime.h>
    
    @implementation NSMutableArray (RunTime)
    
    #pragma mark - 方法替换
    
    + (void)load
    {
        // 方法1
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            // 无效
    //        Class class = [self class];
            // 有效
            Class class = NSClassFromString(@"__NSArrayM");
            
            SEL originalSelector = @selector(addObject:);
            SEL swizzledSelector = @selector(addObjectSafe:);
    
            Method originalMethod = class_getInstanceMethod(class, originalSelector);
            Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
            // judge the method named  swizzledMethod is already existed.
            BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
            // if swizzledMethod is already existed.
            if (didAddMethod)
            {
                class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
            }
            else
            {
                method_exchangeImplementations(originalMethod, swizzledMethod);
            }
        });
        
        // 方法2
        // 无效(异常:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil')
    //        Class class = [self class];
        // 有效
    //    Class class = NSClassFromString(@"__NSArrayM");
    //    Method oldMethod = class_getInstanceMethod(class, @selector(addObject:));
    //    Method newMethod = class_getInstanceMethod(class, @selector(addObjectSafe:));
    //    method_exchangeImplementations(oldMethod, newMethod);
    }
    
    - (void)addObjectSafe:(id)anObject
    {
        if (anObject)
        {
            [self addObjectSafe:anObject];
            NSLog(@"添加成功");
        }
        else
        {
            NSLog(@"添加失败,不能添加 nil 对象");
        }
    }
    
    @end
    

    相关文章

      网友评论

      • 梁森的简书:这种方法能够避免崩溃发生,但最根本的还是得从源头解决问题,避免添加nil(纯属个人观点)
        番薯大佬:@梁森森 我也赞同你的观点,该文章纯粹是当作知识技术分享,实际工作中我也是不建议这样做

      本文标题:runtime方法替换 array添加元素addObject运行

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