定時(shí)器 與RunLoop

一、NSTimer

創(chuàng)建方式

a.這種方式創(chuàng)建的定時(shí)器,在哪個(gè)縣城中創(chuàng)建加到哪個(gè)線程

_timer= [NSTimer scheduledTimerWithTimeInterval:1target:selfselector:@selector(changed) userInfo:nil repeats:YES];

b.該方法創(chuàng)建的NSTimer需要手動(dòng)添加到RunLoop中

_timer = [NSTimer timerWithTimeInterval:1 ?target:self ?selector:@selector(chagned) ?userInfo:nil ?repeats:YES];

注:若不加入到主線程中,定時(shí)器是不會(huì)啟動(dòng)的

[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];

注意:

a.當(dāng)在一個(gè)控制器中Push到下個(gè)界面,而下一個(gè)界面有NSTimer定時(shí)器時(shí),是會(huì)有內(nèi)存泄漏的,所有務(wù)必要進(jìn)行銷毀,通常的做法是在- (void)viewDidDisappear:(BOOL)animated

是銷毀定時(shí)器

通過dealloc即可以發(fā)現(xiàn)有沒有銷毀

b.當(dāng)NSTimer 加入到了滾動(dòng)視圖上,當(dāng)滾動(dòng)視圖的時(shí)候,可能會(huì)出現(xiàn)定時(shí)器不走的情況,典型的就是tabview中cell嵌套了Scrollview 即廣告欄,當(dāng)在滾動(dòng)tabview時(shí),廣告欄圖片不自動(dòng)進(jìn)行輪播了,處理方法如下:

b.1 將定時(shí)器加入到CurrentRunLoop中的CommonModel或者TrackingModel

[[NSRunLoop currentRunLoop] addTimer:_timer forMode:UITrackingRunLoopMode];

b.2利用線程的方式解決NSTime不執(zhí)行的問題

開一個(gè)線程

[NSThread detachNewThreadSelector:@selector(thread) toTarget:selfwithObject:nil];

在線程的響應(yīng)方法中執(zhí)行

- (void)thread

{

_timer= [NSTimer ?scheduledTimerWithTimeInterval:1 ?target:self selector:@selector(chagned) ?userInfo:nil ?repeats:YES];

//讓子線程的RunLoop開啟

[[NSRunLoopcurrent RunLoop] run];

}

//RunLoop的三種模式

// NSDefaultRunLoopMode默認(rèn)

// NSRunLoopCommonModes通用模式

// UITrackingRunLoopMode UI事件傳入模式(用戶的點(diǎn)擊,拖動(dòng)等)

定時(shí)器的相關(guān)方法

a.暫停定時(shí)器

[_timer setFireDate:[NSDate distantFuture]];

b.開始定時(shí)器

[_timersetFireDate:[NSDate distantPast]];

c.銷毀定時(shí)器

[_timer ?invalidate];

_timer=nil;// 一般是一起用(_timer = nil)

二、CADisplayLink

CADisplayLink 同屏幕的刷新率,一般屏幕的默認(rèn)刷新次數(shù)為60/s

使用方式

_displayLink = [CADisplayLink displayLinkWithTarget:selfselector:@selector(update)];

//修改刷新頻率,多少幀刷新一次

_displayLink.frameInterval =60;

//銷毀

//??? [_displayLink invalidate];

//??? _displayLink = nil;

//當(dāng)添加到RunLoop中會(huì)立即執(zhí)行

[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

是否 暫停定時(shí)器

_displayLink.paused=YES;

三、GCD的方式

__blockintj =0;

//第三種創(chuàng)建方式:

timer=dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0,dispatch_get_main_queue());

// intervarlInSeconds每隔多久執(zhí)行一次

// leewayInSeconds允許出現(xiàn)多少誤差,0為最精準(zhǔn)

dispatch_source_set_timer(timer,DISPATCH_TIME_NOW,1*NSEC_PER_SEC,0*NSEC_PER_SEC);

//執(zhí)行的事件

dispatch_source_set_event_handler(timer, ^{

NSLog(@"%d", j++);

});

//執(zhí)行

dispatch_resume(timer);

//停止

//??? dispatch_source_cancel(timer);

Run loop是和線程緊密相關(guān)的非常重要的基礎(chǔ)。一個(gè)Run loop就是一個(gè)事件處理循環(huán),可用于調(diào)度,協(xié)調(diào)輸入事件的接收。Run loop是自動(dòng)管理的。他的作用就是循環(huán)、處理事件。

runloop基本作用

1.保持程序的持續(xù)運(yùn)行

2.處理app的各種事件(比如觸摸事件,定時(shí)器事件,selector事件)

3.節(jié)省CPU資源,提高程序性能。

RunLoop的用處

1.解決NSTimer滑動(dòng)視圖時(shí),定時(shí)器暫停的問題

2.解決單滑動(dòng)ScrollView時(shí)NSURLConnection代理不執(zhí)行的問題

eg:下載數(shù)據(jù)時(shí)滑動(dòng)滾動(dòng)視圖進(jìn)度條不走,不滑動(dòng)時(shí),有繼續(xù)走

解決方案

a.將方法NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];換成

NSURLConnection*connection = [[NSURLConnectionalloc]initWithRequest:requestdelegate:selfstartImmediately:NO];// 注:這里的是否立即執(zhí)行應(yīng)該選擇NO,否則,下面就沒辦法馬上添加到CommonModel中了

b.將connection添加到NSRunLoopCommonModes模式下

[connectionscheduleInRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSRunLoopCommonModes];

[connectionstart]; //開始連接

完整代碼如下

@interfaceViewController()

//解決當(dāng)滑動(dòng)ScrollView時(shí)NSURLConnection代理不執(zhí)行的問題

NSURL*url = [NSURLURLWithString:@"http://dl_dir.qq.com/qqfile/qq/QQforMac/QQ_V2.4.1.dmg"];

NSURLRequest*request = [NSURLRequestrequestWithURL:url];

//??? NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];

NSURLConnection*connection = [[NSURLConnectionalloc]initWithRequest:requestdelegate:selfstartImmediately:NO];

//將connection添加到RunLoop中,并設(shè)置模式

[connectionscheduleInRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSRunLoopCommonModes];

[connectionstart];

#pragma mark - NSURLConnectionDataDelegate

- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data

{

NSLog(@"%ld", data.length);

}

- (void)connectionDidFinishLoading:(NSURLConnection*)connection

{

NSLog(@"下載完成!");

}

最后編輯于
?著作權(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)容