关键地方:
1.封装一个NSTimer 作用:防止循环引用
2.NStimer 在滑动时停止运行,
解决方法:1.通过修改timer默认mode, NSRunLoopCommonModes(滑动时主线程会从NSDefaultRunLoopMode切换为UITrackingRunLoopMode,导致timer停止运行)
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
2.通过创建子线程。
[NSThread detachNewThreadWithBlock:^{
timerTarget.timer = [NSTimer scheduledTimerWithTimeInterval:interval
target:timerTarget
selector:@selector(timeAction:)
userInfo:userInfo
repeats:repeats];
[[NSRunLoop currentRunLoop] addTimer:timerTarget.timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
}];
封装NStimer:
//
// HSTimer.m
// sad
//
// Created by xc on 2022/8/9.
//
#import "HSTimer.h"
@interface HSTimerTarget : NSObject
@property (nonatomic, weak) id target;
@property (nonatomic, assign) SEL selector;
@property (nonatomic, weak) NSTimer* timer;
@end
@implementation HSTimerTarget
- (void)timeAction:(NSTimer *)timer {
if(self.target) {
[self.target performSelector:self.selector withObject:timer.userInfo afterDelay:0.0f];
} else {
[self.timer invalidate];
}
}
@end
@implementation HSTimer
+ (NSTimer *) scheduledTimerWithTimeInterval:(NSTimeInterval)interval
target:(id)aTarget
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)repeats {
HSTimerTarget* timerTarget = [[HSTimerTarget alloc] init];
timerTarget.target = aTarget;
timerTarget.selector = aSelector;
[NSThread detachNewThreadWithBlock:^{
timerTarget.timer = [NSTimer scheduledTimerWithTimeInterval:interval
target:timerTarget
selector:@selector(timeAction:)
userInfo:userInfo
repeats:repeats];
[[NSRunLoop currentRunLoop] addTimer:timerTarget.timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
}];
return timerTarget.timer;
}
@end
//
// HSTimer.h
// sad
//
// Created by xc on 2022/8/9.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface HSTimer : NSObject
+ (NSTimer *) scheduledTimerWithTimeInterval:(NSTimeInterval)interval
target:(id)aTarget
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)repeats;
@end
NS_ASSUME_NONNULL_END
使用:
注意点:在主线程刷新ui
- (NSTimer *)timer {
if (!_timer) {
_timer =
_timer = [HSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeEvent) userInfo:@{@"":@""} repeats:YES];
}
return _timer;
}
- (void)timeEvent {
SK_WeakSelf(self)
dispatch_async(dispatch_get_main_queue(), ^{
weakself.count--;//时间减少
weakself.lab.text = [NSString stringWithFormat:@"%ld:%02ld",weakself.count/60,weakself.count%60];
if (weakself.count == 0) {
//到达时间以后取消定时器
weakself.lab.text = @"去领取";
[weakself stopTimer];
if (weakself.progressOver) {
weakself.progressOver();
}
}
if (weakself.count <= timeNum) {
CGFloat prose = (CGFloat)weakself.count/timeNum;
[weakself setProgress:prose];
}
[weakself setNeedsDisplay];
});
}