iOS消息转发 -- 解决NSNull取值崩溃

iOS消息转发 – 解决NSNull取值崩溃

运用场景

如果数据接口返回的有data中的age是null, 此时取值data[@"age”]会崩溃; 崩溃信息显示:-[NSNull objectForKeyedSubscript:]: unrecognized selector sent to instance 0x104d0bea8;
利用if(data[@"age”]){ 取值 }, 也可以避免崩溃, 但是老是这样写造成大量重复代码, 这时我们只要利用消息转发机制就完全可以避免崩溃, 具体请看下面的示例

# 首先创建一个NSNull分类 NSNull (safeNull)

引入#import
实现以下两个方法

获取方法签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector

标准转发
- (void)forwardInvocation:(NSInvocation *)anInvocation

//
//  NSNull+safeNull.m
//  MessageForward
//
//  Created by 聂银龙 on 2019/8/6.
//  Copyright © 2019 聂银龙. All rights reserved.
//
#import "NSNull+safeNull.h"
#import <objc/message.h>
#define NSNullObjectsArr @[@"", @0, @{
     }, @[]]
@implementation NSNull (safeNull)
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
 {
     
    NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
    if (!signature) {
     
        for (NSObject *obj in NSNullObjectsArr) {
     
            signature = [obj methodSignatureForSelector:aSelector];
            if (signature) {
     
                break;
            }
        }
    }
    return signature;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation 
{
     
    for (NSObject *objc in NSNullObjectsArr) {
     
        if ([objc respondsToSelector:anInvocation.selector]) {
     
            [anInvocation invokeWithTarget:objc];
            return;
        }
    }
}
@end

实际使用

/
//  ViewController.m
//  MessageForward
//
//  Created by 聂银龙 on 2019/8/6.
//  Copyright © 2019 聂银龙. All rights reserved.
//
#import "ViewController.h"
#import "NSNull+safeNull.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
     
    [super viewDidLoad];
    
    id dic = [NSNull null];
    NSLog(@"%@", dic[@"age"]); // 利用消息转发, 从而不会崩溃
}
@end

你可能感兴趣的:(iOS)