在iOS上如何觸發定時任務或延時任務?,ios觸發延時任務
iOS中如何觸發定時任務或延時任務?
定時任務指的是周期性的調用某個方法,實現任務的反覆執行,例如倒計時功能的實現;延時任務指的是等待一定時間後再執行某個任務,例如頁面的延時跳轉等。iOS中控制任務的延時或定時執行的方法有很多,使用中要注意是同步還是非同步,是否會阻塞主線程等問題。實現方法主要如下:
1.performSelector實現延時任務
延時任務可以通過當前UIViewController的performSelector隱式建立子線程實現,不會阻塞主線程:
/* 延遲10s執行任務 */[self performSelector:@selector(task) withObject:nil afterDelay:10];-(void)task{ // delay task }
2.利用sleep實現後面任務的等待,慎用,會阻塞主線程
NSThread sleepForTimeInterval:10.0];
3.GCD實現延時或定時任務
通過GCD實現block代碼塊的延時執行:
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC);dispatch_after(delay, dispatch_get_main_queue(), ^{ // delay task});
GCD也可以用來定義計時器實現定時器功能,可以設定延時開啟計時器,使用中要注意一定要定義強指標指向計時器對象才可讓計時器生效:
/* 必須要用強指標指引計時器才會生效 */@property (nonatomic, strong)dispatch_source_t timer;/* 在指定線程上定義計時器 */dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);/* 開始的時間 */dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));/* 設定計時器 */dispatch_source_set_timer(_timer, when, 1.0 * NSEC_PER_SEC, 0);/* 計時器回調block */dispatch_source_set_event_handler(_timer, ^{ NSLog(@"dispatch_source_set_timer is working!");});/* 開啟計時器 */dispatch_resume(_timer);/* 強引用計時器對象 */self.timer = _timer;
4.NSTimer實現定時任務5.CADisplayLink實現定時任務
CADisplayLink實現的定時器與螢幕重新整理頻率綁定在一起,是一種幀率重新整理,適用於介面的不斷重繪(例如流暢動畫和視頻播放等)。CADisplayLink以特定模式註冊到runloop後,每當螢幕顯示內容重新整理結束就會向CADisplayLink指定的target發送一次訊息,實現target的每幀調用。根據需求也可以設定每幾幀調用一次,預設每幀都調用。另外通過CADisplayLink還可以擷取幀率和時間等資訊。
CADisplayLink實現方法的每幀調用使其計時精度非常高,但如果調用的方法十分耗時,超過一幀的時間間隔,會導致跳幀,跳幀次數取決於CPU的忙碌程度。
- (void)viewDidLoad { [super viewDidLoad]; CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLink_SEL)]; /* 添加到當前啟動並執行RunLoop中啟動 */ [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; /* 暫停、繼續對selector的調用 */ //[displayLink setPaused:YES]; //[displayLink setPaused:NO]; /* 設定每幾幀調用一次selector,預設為1 */ //[displayLink setPreferredFramesPerSecond:2]; /* 移除,不再使用 */ //[displayLink invalidate]; //displayLink = nil;}- (void) displayLink_SEL{ NSLog(@"displayLink is working!");}
列印結果如下,每一幀都調用selector:
2018-02-01 11:48:02.707283+0800 IOSDemo[42328:4522489] displayLink is working!2018-02-01 11:48:02.724375+0800 IOSDemo[42328:4522489] displayLink is working!2018-02-01 11:48:02.742995+0800 IOSDemo[42328:4522489] displayLink is working!