美文网首页iOS
iOS中的NSProxy

iOS中的NSProxy

作者: 伶俐ll | 来源:发表于2018-07-19 15:52 被阅读25次

NSProxy是和NSObject同级的一个类,可以说它是一个虚拟类,它只是实现了<NSObject>的协议,用来专门做消息转发。
详见如下代码:

//LZProxy.h
#import <Foundation/Foundation.h>

@interface LZProxy : NSProxy
+ (instancetype)proxyWithTarget:(id)target;
@property (weak, nonatomic) id target;
@end
#import "LZProxy.h"

@implementation MJProxy

+ (instancetype)proxyWithTarget:(id)target
{
    // NSProxy对象不需要调用init,因为它本来就没有init方法
    MJProxy *proxy = [MJProxy alloc];
    proxy.target = target;
    return proxy;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
    return [self.target methodSignatureForSelector:sel];
}

- (void)forwardInvocation:(NSInvocation *)invocation
{
   //可以在这里拦截方法的参数返回值等相关信息,具体Runtime那篇文章有详细介绍
    [invocation invokeWithTarget:self.target];
}
@end
#import "ViewController.h"
#import "LZProxy.h"

@interface ViewController ()
@property (strong, nonatomic) NSTimer *timer;
@property (strong, nonatomic) CADisplayLink *link;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   
   // 保证调用频率和屏幕的刷帧频率一致,60FPS
    self.link = [CADisplayLink displayLinkWithTarget:[LZProxy proxyWithTarget:self] selector:@selector(linkTest)];
    [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[LZProxy proxyWithTarget:self] selector:@selector(timerTest) userInfo:nil repeats:YES];
}

- (void)timerTest
{
    NSLog(@"%s", __func__);
}
- (void)linkTest
{
    NSLog(@"%s", __func__);
}

- (void)dealloc
{
    NSLog(@"%s", __func__);
    [self.timer invalidate];
}

@end
  • 当给LZProxy类的对象发送消息时,Runtime不会执行消息发送阶段和动态方法解析阶段,直接进行消息转发,系统会直接调用methodSignatureForSelector:方法返回方法签名。
  • 在这里通过实现消息转发,解决了timer、link和控制器的循环引用问题。

另:分析下面程序的打印结果

ViewController *vc = [[ViewController alloc] init];
LZProxy *proxy = [LZProxy proxyWithTarget:vc];
NSLog(@"%d", [proxy isKindOfClass:[ViewController class]]);  //1
  • 给NSProxy类的对象发送消息会直接进入消息转发阶段,调用methodSignatureForSelector:方法,返回方法签名,然后forwardInvocation:方法,在这个方法内部进行消息转发,此时调用isKindOfClass:方法的对象就是vc,因此打印结果是1

相关文章

  • iOS中的NSProxy

    NSProxy是和NSObject同级的一个类,可以说它是一个虚拟类,它只是实现了的协议,用来...

  • NSProxy

    NSProxy——少见却神奇的类 - IOS - 伯乐在线

  • iOS NSProxy

    NSProxy类在分布式对象架构中是很重要的。由于作用比较特别,NSProxy在Cocoa程序中出现频率很低。 N...

  • iOS -NSProxy

    可以看到,它遵守了 NSObject 协议,并且第一个 Ivar 是一个 isa 指针,因此它完全是可以拿来当一个...

  • iOS | NSProxy

    Objective-C作为一种动态消息型语言,其机制不同于Java ,C#等编译型语言.它将数据类型的确定等工作...

  • iOS:NSProxy

    OC 中一个类只有一个父类,这就是单一继承,但是我们可以用协议和NSProxy实现多继承。 1、 protocol...

  • iOS NSProxy

    NSProxy是一个实现了NSObject协议的根类。 苹果的官方文档是这样描述的:NSProxy 是一个抽象基类...

  • iOS 解决NSTimer的循环引用问题

    iOS 13以后可以通过block解决target的强引用问题,如果程序兼顾iOS13以下,那么使用NSProxy...

  • iOS NSProxy探究

    什么是NSProxy NSProxy是和NSObject同级的一个类,可以说它是一个虚拟类,它只是实现了

  • ios开发-NSProxy

    作用:与NSObject属同一个级别,负责将消息转发到真正的target的代理类,实现类似于多继承的功能。 打个比...

网友评论

    本文标题:iOS中的NSProxy

    本文链接:https://www.haomeiwen.com/subject/saetmftx.html