日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS定时器-- NSTimer 和CADisplaylink

發布時間:2023/12/1 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS定时器-- NSTimer 和CADisplaylink 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

iOS定時器-- NSTimer?和CADisplaylink

?

一、iOS中有兩種不同的定時器:

1. ?NSTimer(時間間隔可以任意設定,最小0.1ms)//?If?seconds?is less than or equal to?0.0, this method chooses the nonnegative value of 0.1 milliseconds instead.

2. ?CADisplayLink(時間間隔不能設置,與顯示器刷新頻率一直)

二、創建和啟動定時器的3種方式:

// 方式1

[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(nextImage) userInfo:nil repeats:YES]; //會自動加入當前的runloop消息循環中,不用手寫[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

// 方式2

// 創建 NSTimer 對象

NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(test1) userInfo:nil repeats:YES];

//將剛創建的 NSTimer 對象加到消息循環中, 這樣就會自動啟動定時器

NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

[runLoop addTimer:timer forMode:NSRunLoopCommonModes];

// 方式3

// 創建計時器對象

NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(test1) userInfo:nil repeats:YES]

// 每次調用一次 fire 執行一次 test1方法

[timer fire]; // 執行一次 test 方法

[timer fire]; // 執行一次 test 方法

[timer fire]; // 執行一次 test 方法

[timer fire]; // 執行一次 test 方法

?

三、關于NSRunLoop相關知識:

先看看NSTimer的兩個常用方法:

+ (NSTimer?*)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;?//生成timer但不執行

+ (NSTimer?*)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;?//生成timer并且納入當前線程的run loop來執行

?

NSRunLoop與timer有關方法為:

- (void)addTimer:(NSTimer?*)timer forMode:(NSString?*)mode;?//在run loop上注冊timer

?

理解run loop后,才能徹底理解NSTimer的實現原理,也就是說NSTimer實際上依賴run loop實現的。

主線程已經有run loop,所以NSTimer一般在主線程上運行都不必再調用addTimer: 。

但在非主線程上運行必須配置run loop,NSTimer在非主線程的main方法中使用,示例代碼如下:

- (void)main

{

  NSTimer *myTimer =?[NSTimer scheduledTimerWithTimeInterval:1.0?target:self?selector:@selector(timer:)?userInfo:nil?repeats:YES];

  NSRunLoop *runLoop =?[NSRunLoop?currentRunLoop];

  [runLoop addTimer:myTimer forMode:NSDefaultRunLoopMode]; //實際上這步是不需要,scheduledTimerWithTimeInterval已經納入當前線程運行。如果使用timerWithTimeInterval則需要

  while (xxx條件)

    [runLoop run];

}

實際上這個線程無法退出,因為有timer事件需要處理,[runLoop run]會一直無法返回。解決辦法就是設置一個截止時間:

[runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]];?//每隔10秒檢查下線程循環條件,當然時間值可以根據實際情況來定。

?

特別注意:

我們通常在主線程中使用NSTimer,有個實際遇到的問題需要注意。當滑動界面時,系統為了更好地處理UI事件和滾動顯示,主線程runloop會暫時停止處理一些其它事件,這時主線程中運行的NSTimer就會被暫停。解決辦法就是改變NSTimer運行的mode(mode可以看成事件類型),不使用缺省的NSDefaultRunLoopMode,而是改用NSRunLoopCommonModes,這樣主線程就會繼續處理NSTimer事件了。具體代碼如下:

NSTimer *timer =?[NSTimer?timerWithTimeInterval:1.0?target:self?selector:@selector(timer:)?userInfo:nil?repeats:YES];

[[NSRunLoop?currentRunLoop]?addTimer:timer?forMode:NSRunLoopCommonModes];

?

ios開發經常用到的延遲調用的方法,其實就是在當前線程的run loop上注冊timer來實現定時運行的。所以如果是在非主線程上使用,一定要有一個run loop。

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray?*)modes;

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;

?

四、關于CADisplaylink相關知識

注意:
嚴格意義上講 CADisplayLink 并不是計時器控件, 它是與顯示器刷新頻率一致的。比如顯示的刷新頻率是60赫茲, 那么 CADisplayLink 就會每秒鐘執行60次。正是因為這個原因所以有時也把 CADisplayLink 當做計時器控件來使用。CADisplayLink:每次屏幕刷新的時候就會調用,屏幕一般一秒刷新60次。

//CADisplayLink應用舉例

CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(timerAction)];

[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];??//?添加主運行循環

- (void)timerAction

{?// 注意:這個方法并不會馬上調用drawRect,其實這個方法只是給當前控件添加刷新的標記,等下一次屏幕刷新的時候才會調用drawRect

? ? [self setNeedsDisplay];

}

//如果想把一些文字/圖片等繪制在自定義的WZView上,必須在drawRect里寫代碼

- (void)drawRect:(CGRect)rect {

? ? // 如果以后想繪制東西到view上面,必須在drawRect方法里面,不管有沒有手動獲取到上下文

? ? UIImage *image =? [UIImage imageNamed:@"雪花"];

? ? [image drawAtPoint:CGPointMake(50, _snowY)];

}

?

五、NSTimer 和CADisplaylink的區別:

1.?如果在繪圖的時候需要用到定時器,通常CADisplaylink,?NSTimer很少用于繪圖,因為調度優先級比較低,并不會準時調用。

2. 使用繪圖產生動畫時,一般用CADisplaylink定時器在@selector(timerAction:)方法里調用[self?setNeedsDisplay];方法,因為CADisplaylink是在屏幕刷新時調用一次timerAction:方法,而setNeedsDisplay方法也是在屏幕刷新時調用drawRect方法重繪圖形,二者剛好同步。這樣產生的動畫就非常流暢,不會有卡頓的感覺。

?

?

文章系作者原創,轉載請注明出處:http://www.cnblogs.com/stevenwuzheng/p/5213908.html

如有錯誤,歡迎隨時指正!

?

?

?

?

轉載于:https://www.cnblogs.com/stevenwuzheng/p/5213908.html

總結

以上是生活随笔為你收集整理的iOS定时器-- NSTimer 和CADisplaylink的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。