iOS技术栈

保证字典value为空的时候不会崩溃

2017-07-31  本文已影响31人  loser_彼岸花

#import "NSMutableDictionary+NullSafe.h"

@implementation NSMutableDictionary (NullSafe)

- (void)swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector

{

Class class = [self class];

//得到类的实例方法

Method originalMethod = class_getInstanceMethod(class, origSelector);

Method swizzledMethod = class_getInstanceMethod(class, newSelector);

//向class类中添加 test:方法;函数签名为@@:@,

//    第一个@本class,

//    第二个@添加的方法在本类里面叫做的名字

//    第三个:IMP就是Implementation的缩写,它是指向一个方法实现的指针,每一个方法都有一个对应的IMP。这里需要的是IMP,所以你不能直接写方法,需要用到一个方法class_getMethodImplementation

//    第四个@表示我们要添加的方法的返回值和参数。

BOOL didAddMethod = class_addMethod(class,

origSelector,

method_getImplementation(swizzledMethod),

method_getTypeEncoding(swizzledMethod));

if (didAddMethod) {

//使用该函数可以在运行时动态替换某个类的函数实现,这样做有什么用呢?最起码,可以实现类似windows上hook效果,即截获系统类的某个实例函数,然后塞一些自己的东西进去,比如打个log什么的

class_replaceMethod(class,

newSelector,

method_getImplementation(originalMethod),

method_getTypeEncoding(originalMethod));

} else {

method_exchangeImplementations(originalMethod, swizzledMethod);

}

}

+ (void)load {

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

id obj = [[self alloc] init];

[obj swizzleMethod:@selector(setObject:forKey:) withMethod:@selector(safe_setObject:forKey:)];

});

}

- (void)safe_setObject:(id)value forKey:(NSString *)key {

if (value) {

[self safe_setObject:value forKey:key];

}else {

DebugLog(@"[NSMutableDictionary setObject: forKey:], Object cannot be nil")

}

}

这种解决方法可以避免诸如数组取值越界、字典传空值、removeObjectAtIndex等错误,如下的崩溃就可以避免:

id obj = nil;

NSMutableDictionary *m_dict = [NSMutableDictionary dictionary];

[dict setObject:obj forKey:@"666"];

上一篇 下一篇

猜你喜欢

热点阅读