服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - ios使用NSProxy实现消息转发

ios使用NSProxy实现消息转发

2022-08-04 10:21任淏 IOS

本文主要介绍了ios使用NSProxy实现消息转发,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

简介

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*    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。并实现初始化方法。

?
1
2
3
4
5
6
7
8
9
@interface TargetProxy : NSProxy
 
 
/// 初始化方法,保存两个真实对象
/// @param object1 第一个真实对象
/// @param object2 第二个真实对象
- (instancetype)initWithObject1:(id)object1 object2:(id)object2;
 
@end
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@implementation TargetProxy {
 
    // 保存需要将消息转发到的第一个真实对象
    // 第一个真实对象的方法调用优先级会比第二个真实对象的方法调用优先级高
    id _realObject1;
    // 保存需要将消息转发到的第二个真实对象
    id _realObject2;
}
 
- (instancetype)initWithObject1:(id)object1 object2:(id)object2 {
    _realObject1 = object1;
    _realObject2 = object2;
    
    return self;
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (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 测试

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (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消息转发内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/r360/p/16441909.html

延伸 · 阅读

精彩推荐
  • IOSiOS自定义View实现卡片滑动

    iOS自定义View实现卡片滑动

    这篇文章主要为大家详细介绍了ios自定义View实现卡片滑动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    早起的年轻人6082021-05-30
  • IOSiOS中添加文本链接和图片示例代码

    iOS中添加文本链接和图片示例代码

    这篇文章主要给大家介绍了关于iOS中添加文本链接和图片的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们...

    去你的联盟9652021-03-22
  • IOSiOS中获取系统相册中的图片实例

    iOS中获取系统相册中的图片实例

    这篇文章主要介绍了iOS中获取系统相册中的图片实例,具有一定的参考价值没有需要的朋友可以了解一下。...

    船长_6042021-02-06
  • IOSiOS 获取当前的ViewController的方法

    iOS 获取当前的ViewController的方法

    本篇文章主要介绍了iOS 获取当前的ViewController的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    雨轩_994302021-03-31
  • IOSiOS 适配iPhone X的方法

    iOS 适配iPhone X的方法

    下面小编就为大家分享一篇iOS 适配iPhone X的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    iOS开发网7342021-04-14
  • IOSiOS实现自定义日期选择器示例

    iOS实现自定义日期选择器示例

    本篇文章主要介绍了iOS实现自定义日期选择器示例,可以显示年月日时分,非常具有实用价值,需要的朋友可以参考下。...

    花花08098822021-03-04
  • IOSiOS开发中视图的下拉放大和上拉模糊的效果实现

    iOS开发中视图的下拉放大和上拉模糊的效果实现

    这篇文章主要介绍了iOS开发中视图的下拉放大和上拉模糊的效果实现,本文以秘密App的效果作为示例进行讲解,需要的朋友可以参考下...

    TommyYaphetS1822020-12-23
  • IOSIOS开发环境windows化攻略

    IOS开发环境windows化攻略

    本人主要介绍了IOS开发环境windows化攻略,需要的朋友可以参考下...

    IOS教程网1812020-12-14