美文网首页
iOS内存管理3 - NSTimer循环引用

iOS内存管理3 - NSTimer循环引用

作者: 东旭39 | 来源:发表于2021-03-15 19:56 被阅读0次

    NSTimer提供的timerWithTimeInterval:target:selector,该方法中target会对self进行强引用

        self.timer = [NSTimer timerWithTimeInterval:1 target:weakSelf selector:@selector(fireHome) userInfo:nil repeats:YES];
       [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    

    解决方式1

        self.timer =[NSTimer scheduledTimerWithTimeInterval:3 repeats:YES block:^(NSTimer * _Nonnull timer) {
            
        }];
    

    解决方法二:
    使用VC中的didMoveToParentViewController释放timer

    - (void)didMoveToParentViewController:(UIViewController *)parent{
        // 无论push 进来 还是 pop 出去 正常跑
        // 就算继续push 到下一层 pop 回去还是继续
        if (parent == nil) {
           [self.timer invalidate];
            self.timer = nil;
            NSLog(@"timer 走了");
        }
    }
    

    解决方法三:
    虚基类NSProxy

    @interface LGProxy : NSProxy
    + (instancetype)proxyWithTransformObject:(id)object;
    @end
    
    #import "LGProxy.h"
    
    @interface LGProxy()
    @property (nonatomic, weak) id object;
    @end
    
    @implementation LGProxy
    + (instancetype)proxyWithTransformObject:(id)object{
        LGProxy *proxy = [LGProxy alloc];
        proxy.object = object;
        return proxy;
    }
    
    // 通过消息转发机制,让实际的响应target还是外部self,这一步至关重要,主要涉及到runtime的消息机制。
    // 转移
    // 强引用 -> 消息转发
    
    -(id)forwardingTargetForSelector:(SEL)aSelector {
        return self.object;
    }
    
    @end
    
    

    使用

    -(void)viewDidLoad{
        [super viewDidLoad];
        self.proxy = [LGProxy proxyWithTransformObject:self];
        self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self.proxy selector:@selector(fireHome) userInfo:nil repeats:YES];
    }
    
    - (void)dealloc{
        // VC -> proxy <- runloop
        [self.timer invalidate];
        self.timer = nil;
        NSLog(@"%s",__func__);
    }
    
    

    相关文章

      网友评论

          本文标题:iOS内存管理3 - NSTimer循环引用

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