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]
    

      

  • 相关阅读:
    LeetCode Merge Two Sorted Lists 归并排序
    LeetCode Add Binary 两个二进制数相加
    LeetCode Climbing Stairs 爬楼梯
    034 Search for a Range 搜索范围
    033 Search in Rotated Sorted Array 搜索旋转排序数组
    032 Longest Valid Parentheses 最长有效括号
    031 Next Permutation 下一个排列
    030 Substring with Concatenation of All Words 与所有单词相关联的字串
    029 Divide Two Integers 两数相除
    028 Implement strStr() 实现 strStr()
  • 原文地址:https://www.cnblogs.com/HJiang/p/7308117.html
Copyright © 2011-2022 走看看