iOS 无内存泄露的Timer,减少业务侵入

头文件

#import 

NS_ASSUME_NONNULL_BEGIN
@interface GCTimerHolder : NSObject

@end
@interface GCTimerProxy : NSObject
///开始执行
+ (GCTimerProxy *)timerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer * _Nonnull))block;
- (void)startTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer * _Nonnull))block;
- (void)stopTimer;
@end

NS_ASSUME_NONNULL_END

.m文件


#import "GCTimerProxy.h"
@interface GCTimerHolder ()
@property (nonatomic, strong) NSTimer * timer;
@property (nonatomic, copy) void (^block)(NSTimer *timer);
- (void)startTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block;
- (void)stopTimer;
@end
@implementation GCTimerHolder
- (void)dealloc{
#ifdef DEBUG
    NSLog(@"GCTimerHolder dealloc");
#endif
}
- (void)startTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block{
    [self stopTimer];
    self.block = block;
    NSTimer * timer = [NSTimer timerWithTimeInterval:interval target:self selector:@selector(timeStart) userInfo:nil repeats:repeats];
    [[NSRunLoop currentRunLoop]addTimer:timer forMode:NSRunLoopCommonModes];
    [timer fire];
    self.timer = timer;
}
- (void)stopTimer{
    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
}
- (void)timeStart{
    if (self.block) {
        self.block(self.timer);
    }
}
@end
@interface GCTimerProxy ()
@property (nonatomic, strong) GCTimerHolder * timeHolder;
@end
@implementation GCTimerProxy
- (void)dealloc{
    [self.timeHolder stopTimer];
}
+ (GCTimerProxy *)timerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer * _Nonnull))block{
    GCTimerProxy * timerProxy = [[GCTimerProxy alloc]init];
    [timerProxy startTimerWithTimeInterval:interval repeats:repeats block:block];
    return timerProxy;
}
- (void)startTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer * _Nonnull))block{
    if (self.timeHolder == nil) {
        self.timeHolder = [GCTimerHolder new];
    }
    [self.timeHolder startTimerWithTimeInterval:interval repeats:YES block:block];
}
- (void)stopTimer{
    [self.timeHolder stopTimer];
}
@end

Usage

#import "GCViewController.h"
#import 
@interface GCViewController ()
@property (nonatomic, strong) GCTimerProxy * timer;
@property (nonatomic, strong) GCTimerProxy * timer2;
@end

@implementation GCViewController

- (void)viewDidLoad{
    [super viewDidLoad];
    self.timer = [GCTimerProxy timerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
        NSLog(@"timer1 start");
    }];
    
    self.timer2 = [GCTimerProxy new];
    [self.timer2 startTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
        NSLog(@"===========timer2 start");
    }];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

使用

pod 'GCSafeTimer'

源码地址

你可能感兴趣的:(iOS 无内存泄露的Timer,减少业务侵入)