iOS runtime消息转发非常典型的一个使用案例,nullSafe 判空
最常见的一个崩溃,我们在做http请求的时候,server返回的数据,有的时候会返回null,这就造成了,我们在做数据解析的时候经常崩溃,那怎么处理呢?之前看过一个开源的库,只有二三十行的代码,就是通过runtime消息转发的原理来解决的,将其转发给nil,nil来调用就不会造成崩溃,因为NSNull 是一个对象是有内存地址的,关于nil / Nil / null / NSNull 的解释
我们来看下源码,然后坐下解释
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
//look up method signature
NSMethodSignature *signature = [super methodSignatureForSelector:selector];
if (!signature)
{
for (Class someClass in @[
[NSMutableArray class],
[NSMutableDictionary class],
[NSMutableString class],
[NSNumber class],
[NSDate class],
[NSData class]
])
{
@try
{
if ([someClass instancesRespondToSelector:selector])
{
signature = [someClass instanceMethodSignatureForSelector:selector];
break;
}
}
@catch (__unused NSException *unused) {}
}
}
return signature;
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
invocation.target = nil;
[invocation invoke];
}
仅有这些代码,就可以搞定我们遇到的项目中,不知道什么时候就会崩溃的问题,因为如果我们每次都加判断是否为空,是判断不过来的,所以利用 runtime 的消息转发机制,就可以完美的解决我们的问题。
源码解释
读过我上篇文章的人,应该对消息转发有一定的了解了,这里是利用消息转发的第三部,完整消息转发
1.缓存了常用的一些数据结构类,以便于以后我们从这些对象中查找
2.遍历查找,寻找可以实现此方法的类,如果找到了,就返回这个方法对应的方法签名返回,如果没有找到返回nil,继续下一步
3.将消息发送给nil,因为给nil发送消息不会崩溃
总结
所以最终原理就是讲消息发送给nil,让nil来实现你调用的那个方法 ,比如objectForKey,这样就很完美的实现了我们的问题,作者很巧妙的将他作为NSNull 的分类, 直接将代码导入工程即可,运行时会自动进入消息转发流程,将消息发送给nil。
网友评论