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]
    

      

  • 相关阅读:
    git commit之后未submit,rebase之后找不到自己代码的处理方法
    Objective-C语言--属性和实例变量
    synthesize 与dynamic的区别
    isKindOfClass和isMemberOfClass 区别
    python 报错整理
    使用fastJson 来解析 json
    使用Gson 解析json
    android json数据解析
    Android 常用布局
    cocos2dx 学习代码记录
  • 原文地址:https://www.cnblogs.com/HJiang/p/7308117.html
Copyright © 2011-2022 走看看