美文网首页ios底层原理
NSProxy的使用,以及Timer和DisplayLink循环

NSProxy的使用,以及Timer和DisplayLink循环

作者: MiniCoder | 来源:发表于2020-04-19 14:41 被阅读0次

    在使用NSTimer或者CADisplayLink的的时候,如果我们把当前的控制器作为target传入进入的话,那么他会在runloop中被持有,无法释放。

      self.timer = [NSTimer timerWithTimeInterval:1 target:pro selector:@selector(timeAction) userInfo:nil repeats:true];
    

    这中问题最好的解决方案应该就是使用NSProxy,来打破循环引用。

    • NSProxy是一个实现了NSObject协议的根类。

    苹果的官方文档是这样描述它的:
    NSProxy 是一个抽象基类,它为一些表现的像是其它对象替身或者并不存在的对象定义API。一般的,发送给代理的消息被转发给一个真实的对象或者代理本身引起加载(或者将本身转换成)一个真实的对象。NSProxy的基类可以被用来透明的转发消息或者耗费巨大的对象的lazy 初始化。

    NSProxy实现了包括NSObject协议在内基类所需的基础方法,但是作为一个抽象的基类并没有提供初始化的方法。它接收到任何自己没有定义的方法他都会产生一个异常,所以一个实际的子类必须提供一个初始化方法或者创建方法,并且重载forwardInvocation:方法和methodSignatureForSelector:方法来处理自己没有实现的消息。一个子类的forwardInvocation:实现应该采取所有措施来处理invocation,比如转发网络消息,或者加载一个真实的对象,并把invocation转发给他。methodSignatureForSelector:需要为给定消息提供参数类型信息,子类的实现应该有能力决定他应该转发消息的参数类型,并构造相对应的NSMethodSignature对象。详细信息可以查看NSDistantObject, NSInvocation, and NSMethodSignature的类型说明。
    相信看了这些描述我们应该能对NSProxy有个初步印象,它仅仅是个转发消息的场所,至于如何转发,取决于派生类到底如何实现的。比如我们可以在内部hold住(或创建)一个对象,然后把消息转发给该对象。那我们就可以在转发的过程中做些手脚了。甚至也可以不去创建这些对象,去做任何你想做的事情,但是必须要实现他的forwardInvocation:和methodSignatureForSelector:方法。

    @implementation WXProxy
    
    -(instancetype)initTarget:(id)target{
        _target = target;
        return self;
    }
    
    
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
        NSLog(@"%s",__func__);
        //    return [NSObject instanceMethodSignatureForSelector:sel];
        return [NSObject instanceMethodSignatureForSelector:@selector(init)];
    }
    
    - (id)forwardingTargetForSelector:(SEL)selector {
        NSLog(@"%s",__func__);
        return _target;
    }
    
    
    -(void)forwardInvocation:(NSInvocation *)invocation{
        NSLog(@"%s",__func__);
        //    invocation.target = nil;
        //    [invocation invoke];
        
        void *null = NULL;
        [invocation setReturnValue:&null];
    }
    -(void)dealloc{
        NSLog(@"%s",__FUNCTION__);
    }
    
        self.timer = [NSTimer timerWithTimeInterval:1 target:pro selector:@selector(timeAction) userInfo:nil repeats:true];
    

    相关文章

      网友评论

        本文标题:NSProxy的使用,以及Timer和DisplayLink循环

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