zoukankan      html  css  js  c++  java
  • NSTimer内存泄漏问题

    使用NSTimer的时候可能存储内存泄漏问题,例如:当控制器销毁时,会发现dealloc没有被调用,问题的原因在于timer对控制器对象有强引用,即使是使用了weakSelf

    
    #import "ViewController.h"
    
    
    @interface ViewController ()
    
    @property (nonatomic, strong) NSTimer *timer;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    
        __weak typeof(self) weakSelf = self;
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:weakSelf selector:@selector(timerInvoke:) userInfo:nil repeats:YES];
        self.timer = timer;
    
        self.timer = timer;
        
    }
    
    
    - (void)timerInvoke:(NSTimer *)timer{
        NSLog(@"%s",__func__);
    }
    
    
    - (void)dealloc{
        [self.timer invalidate];
        NSLog(@"%s",__func__);
    }
    
    
    @end
    

     

    如需解决这个问题,就得解决问题的原因timer对target对象的强引用,方式可以修改timer的引用为间接对象target,通过间接对象传递真实监听对象和方法,那么当真实对象的dealloc销毁时,调用[self.timer invalidate]; 那么对象既可以销毁,timer也可以销毁,timer销毁了,间接对象target也就可以销毁.

    
    #import "ViewController.h"
    
    #import "HJTimerTarget.h"
    
    @interface ViewController ()
    
    @property (nonatomic, strong) NSTimer *timer;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    
    //    __weak typeof(self) weakSelf = self;
    //    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:weakSelf selector:@selector(timerInvoke:) userInfo:nil repeats:YES];
    //    self.timer = timer;
    
        NSTimer *timer = [HJTimerTarget scheduledTimerWithTimeInterval:2 target:self selector:@selector(timerInvoke:) userInfo:nil repeats:YES];
        
        self.timer = timer;
        
    }
    
    
    - (void)timerInvoke:(NSTimer *)timer{
        NSLog(@"%s",__func__);
    }
    
    
    - (void)dealloc{
        [self.timer invalidate];
        NSLog(@"%s",__func__);
    }
    
    
    @end
    
    #import <Foundation/Foundation.h>
    
    @interface HWWeakTimerTarget : NSObject
    
    @property (nonatomic, weak) id target;
    @property (nonatomic, assign) SEL selector;
    @property (nonatomic, weak) NSTimer* timer;
    
    + (NSTimer *) scheduledTimerWithTimeInterval:(NSTimeInterval)interval
                                          target:(id)aTarget
                                        selector:(SEL)aSelector
                                        userInfo:(id)userInfo
                                         repeats:(BOOL)repeats;
    
    
    @end
    
    #import "HWWeakTimerTarget.h"
    
    
    @implementation HWWeakTimerTarget
    
    + (NSTimer *) scheduledTimerWithTimeInterval:(NSTimeInterval)interval
                                          target:(id)aTarget
                                        selector:(SEL)aSelector
                                        userInfo:(id)userInfo
                                         repeats:(BOOL)repeats {
        HWWeakTimerTarget* timerTarget = [[HWWeakTimerTarget alloc] init];
        timerTarget.target = aTarget;
        timerTarget.selector = aSelector;
        timerTarget.timer = [NSTimer scheduledTimerWithTimeInterval:interval
                                                             target:timerTarget
                                                           selector:@selector(fire:)
                                                           userInfo:userInfo
                                                            repeats:repeats];
        return timerTarget.timer;
    }
    
    - (void) fire:(NSTimer *)timer {
        if(self.target) {
            [self.target performSelector:self.selector withObject:timer.userInfo];
        } else {
            [self.timer invalidate];
        }
    }
    
    
    - (void)dealloc{
        NSLog(@"%s",__func__);
    }
    
    @end

     运行结果:

    -[ViewController timerInvoke:]
    -[ViewController timerInvoke:]
    -[ViewController timerInvoke:]
    -[ViewController timerInvoke:]
    -[HJTimerTarget dealloc]
    -[ViewController dealloc]
    

      

  • 相关阅读:
    SQL面试题集合
    绕过UAC提示以管理员身份运行程序
    一个在VS2010中不能加载项目的问题
    Windows下硬链接、软链接和快捷方式的区别
    自动化测试中FindWindow与FindWindowEx的使用示例
    在C#中调用批处理文件
    windows的自动登陆问题
    PowerShell操作XML遇到的问题
    MySQL集群MGR架构for单主模式
    MySQL集群MGR架构for多主模式
  • 原文地址:https://www.cnblogs.com/HJiang/p/7308117.html
Copyright © 2011-2022 走看看