메시지 전달을 통해 NSNull 객체 작업으로 인한 충돌 해결

4001 단어
메시지 전송은 조작을 다른 종류에 적용하여 실현하는 데 적용된다
-(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 속성 디스플레이 레이블을 포함하고 있습니다. 만약 UIViewController가 [instance setText:@ "string"방법을 실제 호출한다면 클래스가 setText를 실현하지 못했기 때문입니다. 방법은 위의 두 줄 코드를 통해 전송되고 디스플레이 레이블이 실현됩니다.
#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 

@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

좋은 웹페이지 즐겨찾기