NSTimer不準(zhǔn)的問題及解決

Runloop Timer為什么不準(zhǔn)?
1:Runloop Timer底層使用的timer精度不高;
2:與Runloop底層的調(diào)用機(jī)制有關(guān)系。

情況產(chǎn)生:
1、NSTimer被添加在mainRunLoop中,模式是NSDefaultRunLoopMode,mainRunLoop負(fù)責(zé)所有主線程事件,例如UI界面的操作,復(fù)雜的運(yùn)算使當(dāng)前RunLoop持續(xù)的時(shí)間超過了定時(shí)器的間隔時(shí)間,那么下一次定時(shí)就被延后,這樣就會(huì)造成timer的阻塞。
2:模式的切換,當(dāng)創(chuàng)建的timer被加入到NSDefaultRunLoopMode時(shí),此時(shí)如果有滑動(dòng)UIScrollView的操作,runLoop 的mode會(huì)切換為TrackingRunLoopMode,這是timer會(huì)停止回調(diào)。

解決:
1:在主線程中創(chuàng)建timer,timer添加到當(dāng)前Runloop并設(shè)置RunloopType為NSRunLoopCommonModes。
2: 在子線程中創(chuàng)建timer,GCD操作:dispatch_source_create,創(chuàng)建定時(shí)器,dispatch_source_set_timer :設(shè)置定時(shí)器。dispatch_resume:?jiǎn)?dòng)。
3:CADisplayLink(頻率能達(dá)到屏幕刷新率的定時(shí)器類):displayLinkWithTarget,addToRunLoop

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

/* 定時(shí)器 */
@property (nonatomic, strong) NSTimer *timer;

@property  (nonatomic , strong ) dispatch_source_t  atimer;

@end
#import "ViewController.h"

@interface ViewController ()

{
    UILabel *_label;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
    _label.center = self.view.center;
    _label.textColor = [UIColor blackColor];
    _label.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_label];
    
    //正常用法,作用于主線程的runloop,主線程要處理UI會(huì)影響精準(zhǔn)度,Scollview滑動(dòng)時(shí)mode切換為TrackingRunLoopMode,NSTimer會(huì)停止回調(diào)。
    [self normalUser];
    
    //1、在主線程中切換runloopMode
    [self mainloopchangemode];
    
    //2、異步線程創(chuàng)建NSTimer
    [self asyCreateTimer];
    
    //3、使用CADisplayLink
    [self userCADisplyLink];
}
int i = 0;
-(void)normalUser{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(addtime) userInfo:nil repeats:YES];
}
-(void)mainloopchangemode{
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
-(void)asyCreateTimer{
    self.atimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    dispatch_source_set_timer(self.atimer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 1 * NSEC_PER_SEC );
    dispatch_source_set_event_handler(self.atimer, ^{
        self->_label.text = [NSString stringWithFormat:@"當(dāng)前:%d",i];
        i++;
    });
    dispatch_resume(self.atimer);
}
-(void)userCADisplyLink{
    //較為精準(zhǔn),與屏幕刷新幀率同步,多用戶視圖渲染或繪圖
    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(addtime)];
    [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
-(void)addtime{
    _label.text = [NSString stringWithFormat:@"當(dāng)前:%d",i];
    i++;
}
@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容