美文网首页iOS Developer
自定义不需要手动释放的NSTimer(二)

自定义不需要手动释放的NSTimer(二)

作者: Claire_wu | 来源:发表于2017-08-30 17:09 被阅读292次

    接上篇的讲解,项目实战定义了一个不需要手动释放的NSTimer
    实现思路:了解定时器的同学肯定知道,定时器会保留其目标对象,目标对象又同时持有了定时器。只有在定时器失效时释放目标对象,但程序中反复执行定时任务容易出现内存泄露的问题。首先自定义了一个target,在target里定义了一个weak修饰的timer,target里还定义了timer所应执行任务的方法,并将此方法封装成块来调用的。然后写了一个NSTimer的分类,将target指向我们自定义的target,然后重写了部分定时器相关的方法

    //NSTimer+AutoIncalidate.h
    #import <Foundation/Foundation.h>
    
    typedef void(^ZDTimeTargetBlock)(NSTimer *timer);
    
    @interface ZDTimerTarget : NSObject
    @end
    
    @interface NSTimer (AutoIncalidate)
    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti
                                          block:(ZDTimeTargetBlock)block
                                       userInfo:(id)userInfo
                                        repeats:(BOOL)yesOrNo
                                    existObject:(id)existObj;
    - (void)pauseTimer;
    - (void)resumeTimer;
    - (void)resumeTimerAfterTimeInterval:(NSTimeInterval)interval;
    @end
    
    #import "NSTimer+AutoIncalidate.h"
    
    @interface ZDTimerTarget ()
    @property (nonatomic ,weak)NSTimer *timer;  //注意是weak
    @property (nonatomic,copy) ZDTimeTargetBlock block;  
    @property (nonatomic,weak) id existObj;  //注意是weak
    @end
    
    @implementation ZDTimerTarget
    
    - (id)initWithTimerTargetBlock:(ZDTimeTargetBlock)block timer:(NSTimer *)timer existObj:(id)existObj {
        if (self = [super init]) {
            _block = block;
            _timer = timer;
            _existObj = existObj;
        }
        return self;
    }
    
    - (void)incocaiton {
        if (_existObj) {
            if ((_block)) {
                _block(_timer);
            }
        }else {
            [_timer invalidate];
            _timer = nil;
        }
    }
    
    @end
    
    @implementation NSTimer (AutoIncalidate)
    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)intervval
                                          block:(ZDTimeTargetBlock)block
                                       userInfo:(id)userInfo
                                        repeats:(BOOL)yesOrNo
                                    existObject:(id)existObj
    {
    
        ZDTimerTarget *target = [[ZDTimerTarget alloc] initWithTimerTargetBlock:block timer:nil existObj:existObj];
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:intervval target:target selector:@selector(incocaiton) userInfo:userInfo repeats:yesOrNo];
        target.timer = timer;
        return timer;
    }
    
    -(void)pauseTimer
    {
        if (![self isValid]) {
            return ;
        }
        [self setFireDate:[NSDate distantFuture]];
    }
    
    
    -(void)resumeTimer
    {
        if (![self isValid]) {
            return ;
        }
        [self setFireDate:[NSDate date]];
    }
    
    - (void)resumeTimerAfterTimeInterval:(NSTimeInterval)interval
    {
        if (![self isValid]) {
            return ;
        }
        [self setFireDate:[NSDate dateWithTimeIntervalSinceNow:interval]];
    }
    
    
    @end
    

    相关文章

      网友评论

        本文标题:自定义不需要手动释放的NSTimer(二)

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