RunLoop實(shí)際應(yīng)用

RunLoop是控制線程生命周期并接收事件進(jìn)行處理的機(jī)制.是iOS事件響應(yīng)與任務(wù)處理最核心的機(jī)制.
主線程的RunLoop在應(yīng)用啟動(dòng)時(shí)自動(dòng)創(chuàng)建,讓主程序死循環(huán),保證程序不退出,防止用戶不對(duì)app做出操作導(dǎo)致退出app.
但這個(gè)死循環(huán)是一個(gè)很特殊的死循環(huán), 它能夠在有事情的時(shí)候做事情, 沒(méi)事情做的時(shí)候休息待命, 以節(jié)省CPU資源, 提高程序性能.
實(shí)現(xiàn)省電,流暢,響應(yīng)速度快,用戶體驗(yàn)好

實(shí)際應(yīng)用有:

1.定時(shí)器

注冊(cè)到RunLoop之后,RunLoop會(huì)為其在重復(fù)的時(shí)間點(diǎn)注冊(cè)好事件執(zhí)行.

1.1 NSTimer
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(FunctionName) userInfo:nil repeats:YES];
self.timer = timer;
[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
1.2 CADisplayLink
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(FunctionName)];    
self.link = link;
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

注意:定時(shí)器不使用一定要銷毀!
其中NSRunLoopCommonModes包含kCFRunLoopDefaultMode(NSDefaultRunLoopMode)UITrackingRunLoopMode兩種模式
保證時(shí)鐘在兩種RunLoop運(yùn)行模式下都能被監(jiān)聽(tīng)到.

1.3 GCD

GCD定時(shí)器會(huì)自動(dòng)開(kāi)啟一條子線程,子線程中也會(huì)自己開(kāi)啟了runloop.自己創(chuàng)建,自己管理,全不用我們手動(dòng)管理

//首先聲明屬性
@property (strong, nonatomic) dispatch_source_t timer;
//然后是方法:
- (void)GCDTimer {
    /*
     參數(shù)1 : 需要?jiǎng)?chuàng)建的源的種類, timer 也是一種數(shù)據(jù)源
     參數(shù)2,參數(shù)3: 在你創(chuàng)建timer的時(shí)候直接傳0就可以了
     參數(shù)4: timer觸發(fā)的代碼運(yùn)行的隊(duì)列
     */
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
    /*
     參數(shù)1 : timer定時(shí)器
     參數(shù)2 : 從什么時(shí)間開(kāi)始觸發(fā)定時(shí)器, DISPATCH_TIME_NOW代表現(xiàn)在
     參數(shù)3 : 時(shí)間間隔
     參數(shù)4 : 表示精度, 傳0表示絕對(duì)精準(zhǔn)
     */
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    
    //封裝timer需要觸發(fā)的方法
    dispatch_source_set_event_handler(timer, ^{
        //當(dāng)前線程是子線程
        NSLog(@"GCDTimer-----%@",[NSThread currentThread]);
        NSLog(@"每?jī)擅氪蛴∫淮?);
    });

    //啟用,默認(rèn)是停止的
    dispatch_resume(timer);

    //用強(qiáng)指針引用, 防止timer釋放
    self.timer = timer;
}

2.自動(dòng)釋放池

自動(dòng)釋放池在什么時(shí)候創(chuàng)建?什么時(shí)候銷毀晨抡?
創(chuàng)建: 運(yùn)行循環(huán)檢測(cè)到事件并啟動(dòng)之后淹办,就會(huì)創(chuàng)建自動(dòng)釋放池
銷毀: 一次完整的運(yùn)行循環(huán)結(jié)束之前,會(huì)被銷毀

經(jīng)典錯(cuò)誤:

for (long i = 0; i < largeNumber; ++i) 
{
   NSString *str = [NSString stringWithFormat:@"hello ) %ld", i]; 
   str = [str uppercaseString]; 
   str = [str stringByAppendingString:@" ) world"];
}

分析:
代碼有問(wèn)題税娜,但是并不是說(shuō) largeNumber 沒(méi)有定義悉抵,這個(gè)不是重點(diǎn)
重點(diǎn)是 largeNumber 值我們不知道,如果 largeNumber 值非常大验残,內(nèi)存就會(huì)很高

解決:
引入自動(dòng)釋放池,提前釋放對(duì)象

for (long i = 0; i < largeNumber; ++i) 
{
   @autoreleasepool { 
    NSString *str = [NSString stringWithFormat:@"hello ) %ld", i];
    str = [str uppercaseString]; 
    str = [str stringByAppendingString:@" ) world"];
   }
 } 

其中,在循環(huán)內(nèi)添加自動(dòng)釋放池會(huì)更佳
循環(huán)內(nèi)的運(yùn)行速度比循環(huán)外的要快
循環(huán)外的會(huì)有內(nèi)存峰值,如果峰值太大己肮,會(huì)造成程序閃退

如果在開(kāi)發(fā)中,遇到部份內(nèi)存峰值很高悲关,可以嘗試添加自動(dòng)釋放池


3.操縱線程
3.1可以用RunLoop實(shí)現(xiàn)將一個(gè)函數(shù)調(diào)用在主線程執(zhí)行
[[NSRunLoop mainRunLoop] performSelector:@selector(FunctionName) withObject:nil];

此外還有三種方式可以實(shí)現(xiàn):
1>GCD:

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  // 執(zhí)?耗時(shí)的異步操作...

  dispatch_async(dispatch_get_main_queue(), ^{
  // 回到主線程,執(zhí)?UI刷新操作

  });
});  

2>NSOperation:

NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
NSBlockOperation *operation = [NSBlockOperation blockOpertionWithBlock:^{

}];
[mainQueue addOperation:operation];

3>NSThread:

[self performSelector:@selector(FunctionName) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES modes:nil];
[self performSelectorOnMainThread:@selector(method) withObject:nil];

4>pThread 沒(méi)用過(guò)

pthread_t:線程ID
pthread_attr_t:線程屬性
pthread_create():創(chuàng)建一個(gè)線程
pthread_exit():終止當(dāng)前線程
pthread_cancel():中斷另外一個(gè)線程的運(yùn)行
pthread_join():阻塞當(dāng)前的線程谎僻,直到另外一個(gè)線程運(yùn)行結(jié)束
pthread_attr_init():初始化線程的屬性
pthread_attr_setdetachstate():設(shè)置脫離狀態(tài)的屬性(決定這個(gè)線程在終止時(shí)是否可以被結(jié)合)
pthread_attr_getdetachstate():獲取脫離狀態(tài)的屬性
pthread_attr_destroy():刪除線程的屬性
pthread_kill():向線程發(fā)送一個(gè)信號(hào)
pthread_equal(): 對(duì)兩個(gè)線程的線程標(biāo)識(shí)號(hào)進(jìn)行比較
pthread_detach(): 分離線程
pthread_self(): 查詢線程自身線程標(biāo)識(shí)號(hào)
3.2常駐線程

讓一個(gè)子線程不被銷毀, 等待其他線程發(fā)來(lái)消息, 處理事件
沒(méi)用過(guò)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市寓辱,隨后出現(xiàn)的幾起案子艘绍,更是在濱河造成了極大的恐慌,老刑警劉巖秫筏,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诱鞠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡这敬,警方通過(guò)查閱死者的電腦和手機(jī)航夺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)崔涂,“玉大人阳掐,你說(shuō)我怎么就攤上這事±渎欤” “怎么了锚烦?”我有些...
    開(kāi)封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)帝雇。 經(jīng)常有香客問(wèn)我涮俄,道長(zhǎng),這世上最難降的妖魔是什么尸闸? 我笑而不...
    開(kāi)封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任彻亲,我火速辦了婚禮,結(jié)果婚禮上吮廉,老公的妹妹穿的比我還像新娘苞尝。我一直安慰自己,他們只是感情好宦芦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布宙址。 她就那樣靜靜地躺著,像睡著了一般调卑。 火紅的嫁衣襯著肌膚如雪抡砂。 梳的紋絲不亂的頭發(fā)上大咱,一...
    開(kāi)封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音注益,去河邊找鬼碴巾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛丑搔,可吹牛的內(nèi)容都是我干的厦瓢。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼啤月,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼煮仇!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起谎仲,我...
    開(kāi)封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤浙垫,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后强重,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贸人,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年间景,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艺智。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡倘要,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出十拣,到底是詐尸還是另有隱情封拧,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布夭问,位于F島的核電站泽西,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏缰趋。R本人自食惡果不足惜捧杉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秘血。 院中可真熱鬧味抖,春花似錦、人聲如沸灰粮。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)粘舟。三九已至熔脂,卻和暖如春佩研,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锤悄。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工韧骗, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人零聚。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓袍暴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親隶症。 傳聞我的和親對(duì)象是個(gè)殘疾皇子政模,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容