首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

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

2024-12-16 来源:化拓教育网

接上篇的讲解,项目实战定义了一个不需要手动释放的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
显示全文