iOS下RunLoop的實(shí)際應(yīng)用場(chǎng)景探究

最近這幾天一直在研究RunLoop(它是什么就不延伸了,網(wǎng)上教程很多),總算有點(diǎn)心得,今天主要是記錄下在研究過(guò)程中所寫(xiě)的demo。

本文主要是記錄2個(gè)地方:

  • RunLoop與NSTimer的結(jié)合
  • RunLoop與NSURLConnection的結(jié)合

首先先討論第一個(gè),默認(rèn)情況下NSTimer被創(chuàng)建好之后,是運(yùn)行中Default Mode下的。所以當(dāng)頁(yè)面中有Scroll事件和Timer共存時(shí),一旦Scroll事件正常影響,那么Timer的事件則會(huì)被阻塞得不到任何反應(yīng)!

Default Mode.gif

我們從上圖可以看圖,在2s-4s之間,我拖動(dòng)了UITableView,頂部的數(shù)值并未變化!直到第5s放開(kāi)拖動(dòng)后,數(shù)值會(huì)延續(xù)+1,所以我們可以簡(jiǎn)單的總結(jié):當(dāng)拖動(dòng)時(shí),Timer被凍結(jié)了;松開(kāi)時(shí),Timer被重新喚醒,然后執(zhí)行!

其實(shí)這個(gè)場(chǎng)景用得相對(duì)較少,但是有一個(gè)場(chǎng)景我想可能很多人都碰到過(guò)或可能即將碰到!那就是:
添加商品到購(gòu)物車(chē)后,倒計(jì)時(shí)15分鐘(假設(shè)),如果15分鐘結(jié)束之后,自動(dòng)會(huì)從購(gòu)物車(chē)移除。

我相信很多做購(gòu)物App的人都碰到過(guò)類(lèi)似的需求,大部分人都會(huì)首先使用NSTimer(當(dāng)然還有其他方式)來(lái)每隔1秒判斷一次,這時(shí)候我們?nèi)绻恢繰unLoop的機(jī)制的話,那么我們?cè)陬l繁拖動(dòng)UITableView時(shí)就會(huì)出現(xiàn)時(shí)間差值(因?yàn)橥蟿?dòng)凍結(jié)了NSTimer,所以導(dǎo)致時(shí)間根本就不是15分鐘)!

那么如果解決這個(gè)問(wèn)題呢?大招來(lái)了~~~

  1. 更改RunLoop運(yùn)行Mode
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
或者
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
  1. 將NSTimer放到新的線程(非UI線程)中
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(newThread) object:nil];
    [thread start];

- (void)newThread{
    @autoreleasepool{
        //在當(dāng)前Run Loop中添加timer,模式是默認(rèn)的NSDefaultRunLoopMode
        timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(incrementCounter:) userInfo: nil repeats:YES];
        //開(kāi)始執(zhí)行新線程的Run Loop,如果不啟動(dòng)run loop,timer的事件是不會(huì)響應(yīng)的
        [[NSRunLoop currentRunLoop] run];
    }  
}

OK啦,一旦這樣設(shè)置之后,NSTimer的事件影響就不會(huì)被凍結(jié)了!

Common Mode.gif

然后我們來(lái)討論一下NSURLConnection,NSURLConnection默認(rèn)情況下也是在Default Mode下。

假設(shè)我們有一個(gè)UITableView,UITableView上面有很多UITableViewCell,UITableViewCell上面有一個(gè)UIImageView(你可以想象QQ的聊天頁(yè)面)。這時(shí)候一般我們的需求都是那個(gè)UIImageView的圖片需要你從網(wǎng)絡(luò)上下載,并且異步,下載成功之后更新到UIImageView上!??!

實(shí)際上這個(gè)時(shí)候我們就會(huì)碰到問(wèn)題,因?yàn)槲覀兊腢ITableView是可以任意拖動(dòng)的,所以如果不更改NSURLConnection的運(yùn)行模式,那么在拖動(dòng)過(guò)程中就會(huì)凍結(jié)掉NSURLConnection的RunLoop。這時(shí)候就會(huì)產(chǎn)生2個(gè)不好的想象:

  • UIImageView遲遲得不到圖片數(shù)據(jù),從而導(dǎo)致遲遲無(wú)法設(shè)置image
  • NSURLConnection是有timeout的,所以如果被凍結(jié)時(shí)間過(guò)長(zhǎng),可能會(huì)導(dǎo)致結(jié)果被拋棄

解決此問(wèn)題的代碼如下:

NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15];
NSURLConnection *connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]autorelease];
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[connection start];
最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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