ios使用NSProxy实现消息转发

 更新时间:2022年07月04日 10:15:00   作者:任淏  
本文主要介绍了ios使用NSProxy实现消息转发,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

简介

? 在 iOS 应用开发中,自定义一个类一般需要继承自 NSObject 类或者 NSObject 子类,但是,NSProxy 类不是继承自 NSObject 类或者 NSObject 子类,而是一个实现了 NSObject 协议的抽象基类。

/*?? ?NSProxy.h
?? ?Copyright (c) 1994-2019, Apple Inc. All rights reserved.
*/

#import <Foundation/NSObject.h>

@class NSMethodSignature, NSInvocation;

NS_ASSUME_NONNULL_BEGIN

NS_ROOT_CLASS
@interface NSProxy <NSObject> {
? ? __ptrauth_objc_isa_pointer Class?? ?isa;
}

+ (id)alloc;
+ (id)allocWithZone:(nullable NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
+ (Class)class;

- (void)forwardInvocation:(NSInvocation *)invocation;
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel NS_SWIFT_UNAVAILABLE("NSInvocation and related APIs not available");
- (void)dealloc;
- (void)finalize;
@property (readonly, copy) NSString *description;
@property (readonly, copy) NSString *debugDescription;
+ (BOOL)respondsToSelector:(SEL)aSelector;

- (BOOL)allowsWeakReference API_UNAVAILABLE(macos, ios, watchos, tvos);
- (BOOL)retainWeakReference API_UNAVAILABLE(macos, ios, watchos, tvos);

// - (id)forwardingTargetForSelector:(SEL)aSelector;

@end

NS_ASSUME_NONNULL_END

NSProxy 的作用就是作为一个委托代理对象,将消息转发给一个真实的对象或者自己加载的对象。

为了进一步了解 NSProxy 类的作用,我们来实现一个同事调用 NSMutableString 和 NSMutableArray 两个类中的方法的委托类,模拟多继承。

首先创建 TargetProxy 类,让他继承 NSProxy。并实现初始化方法。

@interface TargetProxy : NSProxy


/// 初始化方法,保存两个真实对象
/// @param object1 第一个真实对象
/// @param object2 第二个真实对象
- (instancetype)initWithObject1:(id)object1 object2:(id)object2;

@end
@implementation TargetProxy {

? ? // 保存需要将消息转发到的第一个真实对象
? ? // 第一个真实对象的方法调用优先级会比第二个真实对象的方法调用优先级高
? ? id _realObject1;
? ? // 保存需要将消息转发到的第二个真实对象
? ? id _realObject2;
}

- (instancetype)initWithObject1:(id)object1 object2:(id)object2 {
? ? _realObject1 = object1;
? ? _realObject2 = object2;
? ??
? ? return self;
}

然后在 TargetProxy.m 文件中,重写 - methodSignatureForSelector: 获取真实对象方法签名,并重写 - forwardInvocation: 方法,调用真实的对象方法。

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
? ? // 获取 _realObject1 中 sel 的方法签名
? ? NSMethodSignature *signature = [_realObject1 methodSignatureForSelector:sel];
? ? // 如果 _realObject1 中有该方法,那么返回该方法的签名
? ? // 如果没有,返回 _realObject1 方法签名
? ? if (signature) {
? ? ? ? return signature;
? ? }
? ? // 获取 _realObject1 中的 sel 的方法签名
? ? signature = [_realObject2 methodSignatureForSelector:sel];
? ? return signature;
}

- (void)forwardInvocation:(NSInvocation *)invocation {
? ? // 获取拥有该方法的真实对象
? ? id target = [_realObject1 methodSignatureForSelector:[invocation selector]] ? _realObject1 : _realObject2;

? ? // 执行方法
? ? [invocation invokeWithTarget:target];
}

最后,进行 Demo 测试

- (void)testTargetProxy {
? ? NSMutableString *string = [NSMutableString string];
? ? NSMutableArray *array = [NSMutableArray array];
? ??
? ? id proxy = [[TargetProxy alloc] initWithObject1:string object2:array];
? ? [proxy appendString:@"This "];
? ? [proxy appendString:@"is "];
? ? [proxy addObject:string];
? ? [proxy appendString:@"a "];
? ? [proxy appendString:@"test!"];
? ??
? ? NSLog(@"The string is length is: %@", [proxy valueForKey:@"length"]);
? ? NSLog(@"count should be 1, it is %ld", [proxy count]);
? ??
? ? if ([[proxy objectAtIndex:0] isEqualToString:@"This is a test!"]) {
? ? ? ? NSLog(@"Appending successful.");
? ? } else {
? ? ? ? NSLog(@"Appending failed,, got: '%@'", proxy);
? ? }
}

运行上面的代码,输入日志如下:

2022-04-02 11:30:35.957145+0800 Demo[19783:586710] SuccessFully create Delegere Proxy automatically.
2022-04-02 11:30:35.959722+0800 Demo[19783:586710] The string is length is: 15
2022-04-02 11:30:35.960175+0800 Demo[19783:586710] count should be 1, it is 1
2022-04-02 11:30:40.086227+0800 Demo[19783:586710] Appending successful.

? 以上说明,我们使用 TargetProxy 类成功的实现了消息转发。

? 当然,在大部分情况下,使用 NSObject 类也可以实现消息转发,实现方式和 NSProxy 类似,但是大部分情况下使用 NSProxy 更加合适。因为:

  • NSProxy 类实现了包括 NSObject 协议在内基类所需的基础方法
  • 通过 NSObject 类实现的代理类不会自动的转发 NSObject 协议中的方法
  • 通过 NSObject 类实现的代理类不会自动的转发 NSObject 类别中的方法

 到此这篇关于ios使用NSProxy实现消息转发的文章就介绍到这了,更多相关ios NSProxy消息转发内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

您可能感兴趣的文章:

相关文章

  • iOS实现自定义起始时间选择器视图

    iOS实现自定义起始时间选择器视图

    本篇文章主要介绍了iOS实现自定义起始时间选择器视图,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • ios基础教程之常见的数组使用方法

    ios基础教程之常见的数组使用方法

    这篇文章主要给大家介绍了关于ios基础教程之常见的数组使用方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-01-01
  • iOS中NSInvocation的基本用法教程

    iOS中NSInvocation的基本用法教程

    NSInvocation是IOS消息传递和方法调用的一个类,下面这篇文章主要给大家介绍了关于iOS中NSInvocation的基本用法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友们可以参考借鉴,下面随着小编来一起看看吧。
    2017-09-09
  • UILabel显示定时器文本跳动问题的解决方法

    UILabel显示定时器文本跳动问题的解决方法

    这篇文章主要给大家介绍了关于UILabel显示定时器文本跳动问题的解决方法,文中通过示例代码介绍的非常详细,对各位iOS开发者们具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • 详解IOS中如何实现瀑布流效果

    详解IOS中如何实现瀑布流效果

    说到瀑布流, 或许大家都不陌生, 瀑布流的实现也有很多种! 从scrollView 到 tableView 书写的瀑布流, 然后再到2012年iOS6 苹果API新加进的collectionView进行的瀑布流封装! 确实,不论是写起来还是用起来都要方便很多!那么下面一起来看看IOS中具体如何实现瀑布流效果。
    2016-08-08
  • 详解 swift3.0 可选绑定共用同一块内存空间的实例

    详解 swift3.0 可选绑定共用同一块内存空间的实例

    这篇文章主要介绍了详解 swift3.0 可选绑定共用同一块内存空间的实例的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-09-09
  • swift3.0网络图片缓存原理简析

    swift3.0网络图片缓存原理简析

    这篇文章主要为大家简析了swift3.0网络图片缓存原理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • iOS13即将到来,iOS推送DeviceToken适配方案详解

    iOS13即将到来,iOS推送DeviceToken适配方案详解

    这篇文章主要介绍了iOS13即将到来,iOS推送DeviceToken适配方案详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • yii框架分类树扩展示例

    yii框架分类树扩展示例

    这篇文章主要介绍了yii框架分类树扩展示例,提供两种方式的分类树格式,表格和下拉框形式的树形结构,需要的朋友可以参考下
    2014-04-04
  • iOS中日志同步获取NSLog重定向以及其他详解

    iOS中日志同步获取NSLog重定向以及其他详解

    在Objective-c开发程序的时候,有专门的日志操作类NSLog,它将指定的输出,输出到(stderr),我们可以利用Xcode的日志输出窗口,下面这篇文章主要给大家介绍了关于iOS中日志同步获取NSLog重定向以及其他的相关资料,需要的朋友可以参考下。
    2017-12-12

最新评论

?


http://www.vxiaotou.com