線程的可選方案
浠水網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),浠水網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為浠水上1000家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的浠水做網(wǎng)站的公司定做!
有時(shí)候,你不想繼承threads或不想自己創(chuàng)建和管理單獨(dú)的線程。例如,你想要一個(gè)定時(shí)器每2秒鐘調(diào)用你的方法,你可能會(huì)寫(xiě)一個(gè)線程一直循環(huán),然后睡眠2秒,然后調(diào)用你的方法。或者你可能想要寫(xiě)代碼處理異步請(qǐng)求,比如從網(wǎng)絡(luò)上下載文件?;蛘弋?dāng)你的iPhone空閑時(shí),你想要繼續(xù)進(jìn)行重量級(jí)的計(jì)算處理。這些都不太容易實(shí)現(xiàn)或者可能會(huì)降低性能。我會(huì)討論一些解決的辦法。
NSTimer
NSTimer并不承諾會(huì)很精確;如果你設(shè)置每0.5秒觸發(fā)一次,實(shí)際上定時(shí)器觸發(fā)的時(shí)間可能在0.55和0.6秒之間。但是,如果你只是想相對(duì)準(zhǔn)確的執(zhí)行周期性任務(wù)的話,這是一個(gè)很好的機(jī)制。
重復(fù)和非重復(fù)NSTimer比較
你可以執(zhí)行重復(fù)或非重復(fù)的定時(shí)器。對(duì)于重復(fù)的定時(shí)器來(lái)說(shuō),定時(shí)器會(huì)在你指定的時(shí)間間隔內(nèi)觸發(fā),不會(huì)停止。如果你想停止的話,你需要手工的使定時(shí)器無(wú)效。對(duì)于非重復(fù)定時(shí)器來(lái)說(shuō),它只會(huì)觸發(fā)一次,然后會(huì)自動(dòng)的變?yōu)闊o(wú)效。對(duì)這兩種情況,一旦定時(shí)器無(wú)效了,你不能在重用它;你必須重新創(chuàng)建一個(gè)定時(shí)器對(duì)象。
要?jiǎng)?chuàng)建一個(gè)定時(shí)器,你可以使用:
+ scheduledTimerWithTimeInterval:target:selector:userInfo: repeats:
或使用:
+ timerWithTimeInterval:target:selector:userInfo:repeats:
第一種方法會(huì)創(chuàng)建一個(gè)新的定時(shí)器,然后添加到當(dāng)前的run loop中,然后返回定時(shí)器對(duì)象給你。第二種方法僅僅創(chuàng)建一個(gè)定時(shí)器對(duì)象;你需要自己通過(guò)調(diào)用[aTimer addTimer: forMethod]來(lái)添加到你自己的run loop中。
當(dāng)時(shí)候重復(fù)定時(shí)器時(shí),如果你要使定時(shí)器變成無(wú)效的話,你需要調(diào)用方法:[aTimer invalidate];
注意:在一個(gè)沒(méi)有run loop的線程中,NSTimer是不能工作的。 |
異步函數(shù)
在很多情況下,異步函數(shù)比線程更輕量級(jí)。例如,iPhone環(huán)境能夠從線程池中重用線程來(lái)處理異步函數(shù)。更進(jìn)一步,如果你需要處理100個(gè)異步函數(shù),OS可能只需要10個(gè)線程,因?yàn)橐粋€(gè)線程能夠處理多個(gè)異步函數(shù)。唯一的問(wèn)題就是,它比你創(chuàng)建一些線程和一個(gè)異步請(qǐng)求來(lái)處理他們看起來(lái)更復(fù)雜。
Listing 6-9 代碼塊創(chuàng)建了一個(gè)異步請(qǐng)求到服務(wù)器上,然后合并返回的結(jié)果創(chuàng)建一個(gè)數(shù)據(jù)對(duì)象。
相比,使用簡(jiǎn)單的線程和異步函數(shù)處理方案:
@autoreleasepool {
NSData *p_w_picpathData = [NSData dataWithContentsOfURL:p_w_picpathURL];
}
在某些情況下,你可能需要寫(xiě)更多的代碼來(lái)獲得更好的性能。你僅僅需要確保實(shí)際上做的什么將對(duì)你有利。
如果你使用異步HTTP請(qǐng)求,你需要運(yùn)行在一個(gè)后臺(tái)線程中。如果很長(zhǎng)一段時(shí)間都沒(méi)有響應(yīng),iOS的策略可能會(huì)殺掉你的應(yīng)用。這會(huì)使得你的應(yīng)用給別人一個(gè)不好的印象。
注意:如果你同時(shí)有很多HTTP調(diào)用,你應(yīng)該考慮創(chuàng)建一個(gè)單獨(dú)的線程來(lái)處理異步調(diào)用,從而避免在主線程上調(diào)用沖突。 |
Idle-Time Notifications 空閑通知
有些事情你只想在系統(tǒng)空閑的時(shí)候做。例如,你想要從iPhone發(fā)送反饋到服務(wù)器上,而你又不想在其他處理正在進(jìn)行或其他用戶(hù)正在和設(shè)備交互的時(shí)候發(fā)送。你只想在用戶(hù)或設(shè)備沒(méi)事可做的時(shí)候發(fā)送。如果是你自己的話,這確實(shí)是一個(gè)很難的事情。不過(guò)高興的是,蘋(píng)果已經(jīng)提供了一個(gè)函數(shù)來(lái)處理了。你可以通過(guò)NSNotificationQueue 使用 NSPostWhenIdle類(lèi)型 來(lái)post一個(gè)通知,像下面的代碼:
你可以看到,它就像使用NSNotificationCenter那樣來(lái)使用;你添加一個(gè)對(duì)象和方法作為觀察者和selector。然后你可以post一個(gè)新的通知到隊(duì)列中,這樣方法就會(huì)在系統(tǒng)空閑的時(shí)候進(jìn)行處理。
iPhone線程測(cè)試
線程的測(cè)試在第二章已經(jīng)討論過(guò)了,所以圖6-13只是一個(gè)簡(jiǎn)單的溫習(xí)。
這個(gè)測(cè)試并沒(méi)有提供太多的信息,除了應(yīng)用中當(dāng)前線程的狀態(tài)。這個(gè)能夠幫助你了解系統(tǒng)是否因?yàn)槭褂锰嗑€程導(dǎo)致負(fù)荷過(guò)重,或線程掛起和等待太長(zhǎng)時(shí)間,這是死鎖的一個(gè)征兆。
總結(jié)
在本章,你學(xué)到了如何使用多線程來(lái)提升你應(yīng)用的性能。概念實(shí)際上是非常簡(jiǎn)單的:你創(chuàng)建一個(gè)新的線程來(lái)處理一些計(jì)算。但是,為了使得你的應(yīng)用正確和安全的運(yùn)行,你需要注意很多細(xì)節(jié)。你同樣需要知道cpu密集型任務(wù)和IO密集型任務(wù),來(lái)確保什么會(huì)導(dǎo)致性能提升,或使得性能下降。你學(xué)到了如何用不同的方法創(chuàng)建,管理,運(yùn)行線程。你同樣學(xué)到了使用鎖的objective-c風(fēng)格和它的語(yǔ)法,線程同步的問(wèn)題,這個(gè)實(shí)際上是非常重要的。