美文网首页
利用消息转发解决对NSNull对象操作导致的崩溃

利用消息转发解决对NSNull对象操作导致的崩溃

作者: 逆光少年 | 来源:发表于2017-08-29 20:02 被阅读47次
消息转发,适用于把操作给另外一个类来实现
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
    if (!signature) {
        signature = [self.displayLabel methodSignatureForSelector:aSelector];
    }
    return signature;
}

-(void)forwardInvocation:(NSInvocation *)anInvocation
{
    SEL selector = [anInvocation selector];
    if ([self.displayLabel respondsToSelector:selector]) {
        [anInvocation invokeWithTarget:self.displayLabel];
    }
}

下面例子中,一个UIViewController包含了UIlable 属性 displayLabel, 如果UIViewController 实例调用[instance setText:@"string"]方法,由于类没有实现setText:方法,通过上面两行代码,将会转发,由 displayLabel 实现。

#import "RootVC.h"

@interface RootVC ()

@end

@implementation RootVC

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.title = @"Root";
    
    [self addButton];
    // Do any additional setup after loading the view.
}

-(void)addButton
{
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(20.0, 100.0, 100.0, 40.0);
    [btn setTitle:@"Next" forState:UIControlStateNormal];
    [btn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(naviNext) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
    
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(20.0, 140.0, 200.0, 30.0)];
    self.displayLabel = label;
    [self.view addSubview:label];
    [label release];
 
    [self setText:@"你好"]; //这里setText是不能被自己接受的,但是应为在下面做了消息转发,最后事件由self.displayLabel 接受了
}

-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
    if (!signature) {
        signature = [self.displayLabel methodSignatureForSelector:aSelector];
    }
    return signature;
}

-(void)forwardInvocation:(NSInvocation *)anInvocation
{
    SEL selector = [anInvocation selector];
    if ([self.displayLabel respondsToSelector:selector]) {
        [anInvocation invokeWithTarget:self.displayLabel];
    }
}


-(void)naviNext
{
   
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
下面是封装的分类
//
//  TestController.m
//  0803test
//
//  Created by Xudongdong on 2017/8/29.
//  Copyright © 2017年 Xudongdong. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NSNull (InternalNullExtention)

@end
//
//  TestController.m
//  0803test
//
//  Created by Xudongdong on 2017/8/29.
//  Copyright © 2017年 Xudongdong. All rights reserved.
//

//来源于 http://blog.rpplusplus.me/blog/2014/03/28/nsnull-category/

#define NSNullObjects @[@"",@0,@{},@[]]

#import "NSNull+InternalNullExtention.h"

@implementation NSNull (InternalNullExtention)

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
    NSMethodSignature* signature = [super methodSignatureForSelector:selector];
    if (!signature) {
        for (NSObject *object in NSNullObjects) {
            signature = [object methodSignatureForSelector:selector];
            if (signature) {
                break;
            }
        }
        
    }
    return signature;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    SEL aSelector = [anInvocation selector];
    
    for (NSObject *object in NSNullObjects) {
        if ([object respondsToSelector:aSelector]) {
            [anInvocation invokeWithTarget:object];
            return;
        }
    }
    
    [self doesNotRecognizeSelector:aSelector];
}


@end

相关文章

  • 利用消息转发解决对NSNull对象操作导致的崩溃

    消息转发,适用于把操作给另外一个类来实现 下面例子中,一个UIViewController包含了UIlable 属...

  • NSMutableDictionary / NSDictiona

    发生场景及原因:绝大多数情况下,我们向NSNull对象发送消息,都会产生崩溃,NSNull对象常见于后台返回数据中...

  • iOS json中null(NSNull)的解决办法

    NSNull 的对象, 如果直接向这个对象发送消息就会直接崩溃。 1、如果你使用AFNetwork 这个库做网络请...

  • iOS开发丨解决json中null/NSNull导致闪退的问题

    在网络请求中,有时候会遇到返回值为NSNull的情况,如果直接赋值给对象会导致崩溃。 解决方法 创建一个NSNul...

  • IOS基础知识-异常崩溃处理篇

    常见的崩溃类型 1.数组越界,nil值初始化导致的崩溃。2.对字典插入nil值,或者读取NSNULL导致的崩溃。3...

  • NullSafe 学习

    作为处理向 NSNull 发送消息导致的崩溃处理框架,NullSafe 应该是最轻量简洁的了,算起来 50行 代码...

  • RabbitMQ事务

        在使用 RabbitMQ 的时候,可以通过消息持久化操作来解决因为服务器的异常崩溃而导致的消息丢失,除此之...

  • iOS-处理网络请求返回空

    当网络请求返回null,然后对数据进行操作就会导致崩溃, 因为NSNull不是字符串,也不是nil,只有一个方法 ...

  • 认识并使用Promise

    Promise 是一个异步操作返回的对象,用来传递异步操作的消息。 可以解决的问题: 解决了回调地狱问题,不会导致...

  • iOS 消息转发

    级别: ★★☆☆☆标签:「iOS」「消息转发」「null([NSNull null])」作者: WYW审校: Q...

网友评论

      本文标题:利用消息转发解决对NSNull对象操作导致的崩溃

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