NSTimer 滑动导致失效

这篇博客介绍了如何在iOS开发中封装NSTimer以防止循环引用,并解决滑动时定时器停止运行的问题。通过修改timer的mode为NSRunLoopCommonModes和创建子线程的方法确保了定时器在滑动时仍能继续运行。同时提供了一个名为HSTimer的封装类,用于更方便地创建和管理NSTimer。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关键地方:

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];
    });
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值