iOS架构师_代理模式(NSProxy)

我们通过NSProxyDemo案例来更进一步的了解代理模式

创建AbstarctProxy类
AbstarctProxy.h

#import <Foundation/Foundation.h>

@interface AbstarctProxy : NSProxy

// 代理属性
@property (nonatomic, weak) id delegate;

@end

创建空消息垃圾处理类AbstarctSpamMessages
AbstarctSpamMessages.h

#import <Foundation/Foundation.h>

@interface AbstarctSpamMessages : NSObject
+ (instancetype)sharedInstance;
@end

AbstarctSpamMessages.m

#import "AbstarctSpamMessages.h"

@implementation AbstarctSpamMessages

+ (instancetype)sharedInstance
{
    static id sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

// 空的垃圾机制方法
- (void)emptySpamMessages:(NSArray *)parameter withString:(NSString *)str{
    NSLog(@"处理垃圾消息");
}

@end

AbstarctProxy.m

#import "AbstarctProxy.h"
#import "AbstarctSpamMessages.h"
#import <objc/message.h>

@implementation AbstarctProxy
// 方法签名
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
    // 如果支持这个消息,就将这个方法签名返回回去
    if ([self.delegate respondsToSelector:sel]) {
        return [self.delegate methodSignatureForSelector:sel];
    } else {
        AbstarctSpamMessages *message = [AbstarctSpamMessages sharedInstance];
        return [message methodSignatureForSelector:NSSelectorFromString(@"emptySpamMessages:withString:")];
    }
}

// 配发消息
- (void)forwardInvocation:(NSInvocation *)invocation {
    // 1. 获取SEL
    SEL selector = [invocation selector];

    // 2. 判断代理响应
    if ([self.delegate respondsToSelector:selector]) {
        // 设置代理
        [invocation setTarget:self.delegate];
        // 执行方法,派发消息
        [invocation invoke];
    }
    else {
        //  获取参数
       NSString *selectorString = NSStringFromSelector(invocation.selector);
        // 1.替换
        invocation.selector = NSSelectorFromString(@"emptySpamMessages:withString:");
        // 2.再次回去单例对象
         AbstarctSpamMessages *message = [AbstarctSpamMessages sharedInstance];
        // 3. 设置代理. 代理就是专门处理垃圾数据的一个对象
        [invocation setTarget:message];

        // 获取当前控制器的类(ContentProxy)
        const char *className = class_getName([self class]);
        NSArray *parmater = nil;
        NSString *str = @"666";

        // 判断代理
        if (self.delegate) {
            parmater = @[[NSString stringWithUTF8String:className], selectorString,str];
        } else {
            parmater = @[[NSString stringWithUTF8String:className], selectorString];
        }
        // 因为0 1 被两个隐式参数占用self,_cmd. 分别表示的是target和selector
        [invocation setArgument:&parmater atIndex:2];
        [invocation setArgument:&str atIndex:3];
        // 执行方法,派发消息
        [invocation invoke];
    }

}

@end

创建MessagesProtocol协议类

#import <Foundation/Foundation.h>

@protocol MessagesProtocol <NSObject>

- (void)helloWorld;

@end

创建ContentProxy抽象类,继承自AbstarctProxy
ContentProxy.h

#import "AbstarctProxy.h"
#import "MessagesProtocol.h"

@interface ContentProxy : AbstarctProxy <MessagesProtocol>

@end

ViewController调用

#import "ViewController.h"
#import "ContentProxy.h"

@interface ViewController () <MessagesProtocol>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    ContentProxy *proxy = [ContentProxy alloc];
    proxy.delegate = self;

    [proxy helloWorld];
}


@end

当我们传递一个空的方法helloWorld时,就会收到打印日志

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值