RunLoop應(yīng)用

在我的另一篇文章RunLoop簡單介紹了關(guān)于runLoop基礎(chǔ)知識和NSTimer時runloop簡單應(yīng)用, 下面看下怎么使用RunLoop。

一歉眷、Runloop的啟動

在談到RunLoop與線程的關(guān)系時, 每個人都會說主線程的RunLoop是默認(rèn)自動創(chuàng)建啟動的,子線程的 RunLoop 需要手動創(chuàng)建,手動啟動, 這是在多數(shù)博文里都寫到的,但是主線程的RunLoop是怎樣啟動, 又怎樣手動創(chuàng)建的呢

1. 主線程的RunLoop是默認(rèn)啟動的
  • 先看下程序啟動時都做了什么,此處盜圖
    程序啟動過程.png

下面看下main()函數(shù)

int main(int argc, char * argv[]) {
   @autoreleasepool {
       return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
   }
}

在main()函數(shù)里只調(diào)用一個UIApplicationMain()函數(shù), 先點進(jìn)去看下UIApplicationMain函數(shù)

1. UIKIT_EXTERN int UIApplicationMain(int argc, char * _Nonnull * _Null_unspecified argv, NSString * _Nullable principalClassName, NSString * _Nullable delegateClassName);

從上面UIApplicationMain函數(shù)看到返回值是int類型,那么開始改造下代碼,看UIApplicationMain()返回的是什么


int main(int argc, char * argv[]) {
    @autoreleasepool {

//        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

        // 開始改造main函數(shù)
        NSLog(@"調(diào)用UIApplicationMain函數(shù)");
        
        int who = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        NSLog(@"UIApplicationMain函數(shù)的返回值: %d", who);
        
        return who;
    }
}

運行試下, 沒有打印返回值who穿铆。可以看出UIApplicationMain函數(shù)開啟了一個和主線程相關(guān)的RunLoop,導(dǎo)致UIApplicationMain不會返回褂萧,一直在運行中,也就保證了程序的持續(xù)運行葵萎。

2. 子線程開啟RunLoop

子線程的 RunLoop 需要手動創(chuàng)建,手動啟動

// 子線程 開啟 RunLoop
    // 創(chuàng)建子線程
    _thead = [[NSThread alloc] initWithTarget:self selector:@selector(startRunLoop) object:nil];
    // 開啟 子線程
    [_thead start];

- (void)startRunLoop
{
    // 獲取 currentRunLoop
    NSRunLoop *runloop = [NSRunLoop currentRunLoop];
    
    // 因為在子線程中開啟runloop 至少需要一個timer 或者 source ,runloop 才會啟動. addPort 是比添加timer 更好的方式
    [runloop addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
    
    // 開啟 runloop
    [runloop run];
}

注意 runloop 在線程中獲取就是創(chuàng)建

RunLoop應(yīng)用場景

下面介紹幾個RunLoop應(yīng)用場景

1. 子線程的NSTimer

在子線程中添加定時器, 必須手動創(chuàng)建并開啟RunLoop, 將Timer添加進(jìn)創(chuàng)建的runloop中, 否則定時器無效导犹。

    _thead = [[NSThread alloc] initWithBlock:^{
        
        NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerTest) userInfo:nil repeats:YES];
        
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] run];
        
    }];
    
    [_thead start];
2. 滑動與圖片刷新

問題: tableview的cell中的imageView, 需要從網(wǎng)絡(luò)加載的圖片的時候,上下滑動動tableView羡忘,異步線程會去獲取圖片谎痢,獲取完成后主線程就會設(shè)置cell的圖片,但是會造成卡頓卷雕。
解決 滑動tableView的時候节猿,RunLoop是在 UITrackingRunLoopMode下進(jìn)行,此時不會去設(shè)置圖片漫雕,所以可以設(shè)置將圖片的任務(wù)在NSDefaultRunLoopMode下進(jìn)行滨嘱,即當(dāng)tableView滑動停止的時候,再去設(shè)置圖片浸间。

[_imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@""] afterDelay:0.5 inModes:@[NSDefaultRunLoopMode]]; 
3. 常駐子線程

因為在子線程中開啟runloop 至少需要一個timer 或者 source ,runloop 才會啟動太雨。所以想要保持線程長期運轉(zhuǎn),必須讓子線程一直處理事件魁蒜∧野猓可以在子線程中加入RunLoop吩翻,并且給Runloop設(shè)置item,防止Runloop自動退出宪拥。

  • a. 添加Timer ---- 參考上文中 子線程的NSTimer
  • b. 添加事件源 ---- 參考上文中 子線程開啟RunLoop

關(guān)于RunLoop的應(yīng)用場景還有很多, 如果感興趣的話, 推薦去看看 我的runloop學(xué)習(xí)筆記 寫得非常好, 里面都是實際項目中的使用點, 還附有Demo仿野。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市她君,隨后出現(xiàn)的幾起案子脚作,更是在濱河造成了極大的恐慌,老刑警劉巖缔刹,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件球涛,死亡現(xiàn)場離奇詭異,居然都是意外死亡校镐,警方通過查閱死者的電腦和手機亿扁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸟廓,“玉大人从祝,你說我怎么就攤上這事∫眨” “怎么了牍陌?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長员咽。 經(jīng)常有香客問我毒涧,道長,這世上最難降的妖魔是什么贝室? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任契讲,我火速辦了婚禮,結(jié)果婚禮上滑频,老公的妹妹穿的比我還像新娘捡偏。我一直安慰自己,他們只是感情好误趴,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布霹琼。 她就那樣靜靜地躺著,像睡著了一般凉当。 火紅的嫁衣襯著肌膚如雪枣申。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天看杭,我揣著相機與錄音忠藤,去河邊找鬼。 笑死楼雹,一個胖子當(dāng)著我的面吹牛模孩,可吹牛的內(nèi)容都是我干的尖阔。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼榨咐,長吁一口氣:“原來是場噩夢啊……” “哼介却!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起块茁,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤齿坷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后数焊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體永淌,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卑笨。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖褐着,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布悬嗓,位于F島的核電站,受9級特大地震影響裕坊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜燕酷,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一籍凝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧苗缩,春花似錦饵蒂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泻肯,卻和暖如春渊迁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背灶挟。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工琉朽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人稚铣。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓箱叁,卻偏偏與公主長得像墅垮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子耕漱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351

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

  • 一算色、RunLoop基本概念RunLoop從字面意思上看:運行循環(huán)跑圈RunLoop的基本作用:保持程序的持續(xù)運行處...
    雷鳴1010閱讀 336評論 0 0
  • 說明iOS中的RunLoop使用場景1.保持線程的存活,而不是線性的執(zhí)行完任務(wù)就退出了<1>不開啟RunLoop的...
    野生塔塔醬閱讀 6,794評論 15 109
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,093評論 1 32
  • 概述 RunLoop作為iOS中一個基礎(chǔ)組件和線程有著千絲萬縷的關(guān)系螟够,同時也是很多常見技術(shù)的幕后功臣灾梦。盡管在平時多...
    陽明先生_X自主閱讀 1,096評論 0 17
  • 代碼在 RunLoopDemo 中。 RunLoop 與 performSelector 第一個 ViewCont...
    愛笑的云里看夢閱讀 1,663評論 0 5