iOS设计模式 - 代理

简介:

iOS设计模式 - 代理

 

原理图

 

说明

1. 代理模式大家都用过,但用抽象基类NSProxy实现代理估计鲜有人用

2. 本人用NSProxy实现了代理模式,对于理解消息转发机制有点帮助

 

源码

https://github.com/YouXianMing/iOS-Design-Patterns


//
//  AbstractProxy.h
//  AppProxy
//
//  Created by YouXianMing on 15/8/4.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface AbstractProxy : NSProxy

/**
 *  被代理对象
 */
@property (nonatomic, weak) id  customer;

/**
 *  代理客户
 *
 *  @param customer 实现了某种协议的客户
 *
 *  @return 代理对象
 */
- (instancetype)initWithCustomer:(id)customer;

@end


//
//  AbstractProxy.m
//  AppProxy
//
//  Created by YouXianMing on 15/8/4.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import <objc/runtime.h>
#import "AbstractProxy.h"
#import "AbstractExcute.h"

@implementation AbstractProxy

- (instancetype)initWithCustomer:(id)customer {

    self.customer = customer;
    return self;
}

#pragma mark - NSProxy

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    
    if ([self.customer respondsToSelector:aSelector]) {
        
        return [self.customer methodSignatureForSelector:aSelector];
        
    } else {
        
        AbstractExcute *excute = [AbstractExcute shareInstance];
        return [excute methodSignatureForSelector:NSSelectorFromString(@"nullExcute:")];
    }
}

- (void)forwardInvocation:(NSInvocation *)invocation {
    
    SEL selector = [invocation selector];
    if ([self.customer respondsToSelector:selector]) {
        
        [invocation setTarget:self.customer];
        [invocation invoke];
        
    } else {
    
        NSString *selectorString = NSStringFromSelector(invocation.selector);
        
        invocation.selector    = NSSelectorFromString(@"nullExcute:");
        AbstractExcute *excute = [AbstractExcute shareInstance];
        [invocation setTarget:excute];
        
        const char *className      = class_getName([self class]);
        NSArray    *classNameArray = nil;
        if (self.customer) {
            
            classNameArray = @[[NSString stringWithUTF8String:className], selectorString, @""];
            
        } else {
        
            classNameArray = @[[NSString stringWithUTF8String:className], selectorString];
        }
        
        [invocation setArgument:&classNameArray atIndex:2];
        [invocation invoke];
    }
}

@end


//
//  AbstractExcute.h
//  AppProxy
//
//  Created by YouXianMing on 15/8/4.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface AbstractExcute : NSObject

+ (instancetype)shareInstance;

@end


//
//  AbstractExcute.m
//  AppProxy
//
//  Created by YouXianMing on 15/8/4.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import "AbstractExcute.h"

@implementation AbstractExcute

+ (instancetype)shareInstance {

    static AbstractExcute *sharedAbstractExcute = nil;
    
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        sharedAbstractExcute = [[self alloc] init];
    });
    
    return sharedAbstractExcute;
}

- (void)nullExcute:(NSArray *)className {

    if (className.count == 3) {
        
        NSLog(@"%@ 设置了代理,但该代理没有实现 %@ 方法", className[0], className[1]);
        
    } else {
    
        NSLog(@"%@ 没有设置代理,方法 %@ 没有执行", className[0], className[1]);
    }
    
}

@end

细节

NSProxy子类实现的关键所在

 


目录
相关文章
|
5月前
|
设计模式 XML JSON
二十三种设计模式全面解析-代理模式进阶篇:揭秘远程代理
二十三种设计模式全面解析-代理模式进阶篇:揭秘远程代理
135 0
|
设计模式 测试技术 iOS开发
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(1)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(1)
265 0
|
3天前
|
设计模式 网络协议 Java
05.静态代理设计模式
《静态代理设计模式》详细介绍了静态代理的基本概念、原理与实现、应用场景及优缺点。主要内容包括静态代理的由来、定义、使用场景、实现方式、结构图与时序图,以及其在降低耦合、保护对象权限等方面的优势。同时,文章也指出了静态代理的局限性,如缺乏灵活性、难以复用、难以动态添加功能等,并介绍了动态代理如何弥补这些不足。最后,通过多个实际案例和代码示例,帮助读者更好地理解和应用静态代理模式。
32 4
|
1月前
|
设计模式 Java Spring
spring源码设计模式分析-代理设计模式(二)
spring源码设计模式分析-代理设计模式(二)
|
设计模式 API iOS开发
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(3)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(3)
443 0
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(3)
|
设计模式 API iOS开发
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(2)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(2)
300 0
|
设计模式 iOS开发
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(6)
带你读《2022技术人的百宝黑皮书》——淘宝iOS扫一扫架构升级 - 设计模式的应用(6)
278 0
|
5月前
|
设计模式 缓存 安全
设计模式-代理模式(静态代理、动态代理、cglib代理)、代理模式和装饰者模式的区别
设计模式-代理模式(静态代理、动态代理、cglib代理)、代理模式和装饰者模式的区别
|
5月前
|
设计模式 安全 Java
静态代理还是动态代理?来聊聊Java中的代理设计模式
代理模式(Proxy Design Pattern)是一种结构型设计模式,为一个对象提供一个代理对象,然后使用代理对象控制对原对象的引用。即通过代理对象访问目标对象。被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象。
48 0
静态代理还是动态代理?来聊聊Java中的代理设计模式