美文网首页
iOS NSTimer

iOS NSTimer

作者: 小罗哦吧 | 来源:发表于2019-08-24 13:58 被阅读0次

    计时器是一种很方便的对像。由于定时器灰保留起目标对象,所以会造成循环引用。内存释放的了。大家可以建立一个NSTimer然后在dealloc看看会不会进来。

    有二种方法解决
    1:使用block 如果block里面用的是一个弱指针的话block就会对外面的对象产生弱应用 。

     __weak typeof(self) weakSelf = self;
       self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
            [weakSelf timerTest];
       }];
    
    

    看到这里有人会说我这样不也可以吗

    __weak typeof(self) weakSelf = self; 
     self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:weakSelf selector:@selector(timerTest) userInfo:nil repeats:YES]
    

    运行你会发现还是不行,为什么呢?其实在NSTimer 里面你会发现aTarget在源代码里面已经被强引用了所以外面不管怎么修改都是不行的。block则不一样。

    2.建立一个中间类 在中间类把aTarget弱应用

    #import <Foundation/Foundation.h>
    
    @interface LSProxy : NSProxy
    + (instancetype)proxyWithTarget:(id)target;
    @property (weak, nonatomic) id target;
    
    
    #import "LSProxy.h"
    
    @implementation LSProxy
    
    + (instancetype)proxyWithTarget:(id)target
    {
        // NSProxy对象不需要调用init,因为它本来就没有init方法
        LSProxy *proxy = [LSProxy alloc];
        proxy.target = target;
        return proxy;
    }
    //消息转发 交给其他对象处理
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
    {
        return [self.target methodSignatureForSelector:sel];
    }
    
    - (void)forwardInvocation:(NSInvocation *)invocation
    {
        [invocation invokeWithTarget:self.target];
    }
    
    然后在其他地方调用
     self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[LSProxy proxyWithTarget:self] selector:@selector(timerTest) userInfo:nil repeats:YES];
    

    为什么要用NSProxy?NSProxy事专门用来处理消息转发的效率比NSObject高

    相关文章

      网友评论

          本文标题:iOS NSTimer

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