iOS - RunLoop - 胡謅

RunLoop

本來一個線程只能跃脊,處理一個任務(wù)流就退出淮野,執(zhí)行完成該任務(wù)流就退出銷往捧书。單我們希望,線程能隨時處理問題而不退出骤星。模型基本如下

func loop(){
    do{
        var message = getMessage()
        handleMessage(message)
    }while(message != quilt)
}

該模型線程一直在跑经瓷,我們希望,當(dāng)沒有任務(wù)要處理的時候洞难,線程就休眠舆吮,那么RunLoop就應(yīng)運(yùn)而生了

iOS中有2套關(guān)于RunLoop的API:

1.NSRunLoop 線程不安全
2.CFRunLoopRef 線程安全

RunLoop And NSThread

RunLoop和線程是一一對應(yīng)的關(guān)系,一個線程有且只有一個RunLoop,而且還是默認(rèn)沒有開啟的(主線程的RunLoop是默認(rèn)開啟的)

 NSRunLoop.currentRunLoop()
 NSRunLoop.mainRunLoop()
2套api
 CFRunLoopGetCurrent()
 CFRunLoopGetMain()

RunLoopMode

系統(tǒng)默認(rèn)注冊了5個model色冀,暫時只有這3個有點(diǎn)意義

  • NSDefaultRunLoopMode:App的默認(rèn)Mode潭袱,通常主線程是在這個Mode下運(yùn)行
  • UITrackingRunLoopMode:界面跟蹤 Mode,用于 ScrollView 追蹤觸摸滑動(滑動的時候锋恬,主線程的RunLoop在這個模式下運(yùn)行)屯换,保證界面滑動時不受其他 Mode 影響
  • NSRunLoopCommonModes: 這是一個占位用的Mode,不是一種真正的Mode(包含上面2個model的情況)

RunLoop 和 NSTimer

1.mainThread主線程

let myT = NSTimer(timeInterval: 3, target: self, selector: Selector("circleAction"), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(myT, forMode: NSDefaultRunLoopMode)//這個模式下會在普通模式下運(yùn)行与学,滑動scrollView的時候?qū)⒉荒苡|發(fā)定時器
NSRunLoop.currentRunLoop().addTimer(myT, forMode: UITrackingRunLoopMode)//只有在滑動scrollview的時候觸發(fā)
//NSRunLoopCommonModes滑動和不滑動都能觸發(fā)這個定時器

2.otherThread其他線程

 let t = NSTimer(timeInterval: 2, target: self, selector: Selector("circleAction"), userInfo: nil, repeats: true)
 let r = NSRunLoop.currentRunLoop()
 r.addTimer(t, forMode: NSRunLoopCommonModes)//其他線程N(yùn)SRunLoopCommonModes和NSDefaultRunLoopMode才會執(zhí)行
 r.run()//啟動其他線程的RunLoop

RunLoop 和 Observer

觀察該RunLoop的狀態(tài)

        // 1.創(chuàng)建Observer
        // 第一個參數(shù):用于分配該observer對象的內(nèi)存
        // 第二個參數(shù):用以設(shè)置該observer所要關(guān)注的的事件
        // 第三個參數(shù):用于標(biāo)識該observer是在第一次進(jìn)入run loop時執(zhí)行, 還是每次進(jìn)入run loop處理時均執(zhí)行
        // 第四個參數(shù):用于設(shè)置該observer的優(yōu)先級
        // 第五個參數(shù): observer監(jiān)聽到事件時的回調(diào)block
        let observe = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, CFRunLoopActivity.AllActivities.rawValue, true, 0) { (o: CFRunLoopObserver!, a:CFRunLoopActivity) -> Void in 
            switch a {
           case CFRunLoopActivity.Entry:
                print("RunLoop Entry")
            case CFRunLoopActivity.BeforeTimers:
                print("RunLoop BeforeTimers")
            case CFRunLoopActivity.BeforeSources:
                print("RunLoop BeforeSources")
            case CFRunLoopActivity.BeforeWaiting:
                print("RunLoop BeforeWaiting")
            case CFRunLoopActivity.AfterWaiting:
                print("RunLoop 等待后")
            case CFRunLoopActivity.Exit:
                print("RunLoop 退出")//切換model的時候會退出彤悔,再進(jìn)入
            default:
                print("---------------------:\(a)")
                break;
            }
        }
        // 2.添加監(jiān)聽
        /*
        第一個參數(shù): 給哪個RunLoop添加監(jiān)聽
        第二個參數(shù): 需要添加的Observer對象
        第三個參數(shù): 在哪種模式下監(jiān)聽
        */
        CFRunLoopAddObserver(CFRunLoopGetMain(), observe, kCFRunLoopDefaultMode);
//滑動UIScrollview的時候輸出:
RunLoop BeforeTimers
RunLoop BeforeSources
RunLoop BeforeWaiting
RunLoop 等待后
RunLoop BeforeTimers
RunLoop BeforeSources
RunLoop 退出 //滑動先退出原來的model,在進(jìn)入下一個model癣防,切換model
RunLoop Entry
RunLoop BeforeTimers
RunLoop BeforeSources
RunLoop BeforeWaiting

應(yīng)用場景:AsyncDisplayKit,在后臺線程維護(hù)一套和UI組件相同的屬性蜗巧,在合適的時機(jī)(監(jiān)聽主線程的RunLoop,當(dāng)RunLoop進(jìn)入BeforeWaiting的時候進(jìn)行UI刷新)在主線程上蕾盯,把維護(hù)的屬性和UI自有屬性同步。

RunLoop 和 NSMachPort

應(yīng)用場景,后臺開辟一個線程蓝丙,來監(jiān)聽一個port级遭。通常情況下,調(diào)用者需要持有這個 NSMachPort (mach_port) 并在外部線程通過這個 port 發(fā)送消息到 loop 內(nèi)

 let r = NSRunLoop.currentRunLoop()
 let markPort = NSMachPort(machPort: 22)
 r.addPort(markPort, forMode: NSRunLoopCommonModes)
 r.run()

案例

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末渺尘,一起剝皮案震驚了整個濱河市挫鸽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸥跟,老刑警劉巖丢郊,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異医咨,居然都是意外死亡枫匾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門拟淮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來干茉,“玉大人,你說我怎么就攤上這事很泊〗浅妫” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵委造,是天一觀的道長戳鹅。 經(jīng)常有香客問我,道長昏兆,這世上最難降的妖魔是什么枫虏? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上模软,老公的妹妹穿的比我還像新娘伟骨。我一直安慰自己,他們只是感情好燃异,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布携狭。 她就那樣靜靜地躺著,像睡著了一般回俐。 火紅的嫁衣襯著肌膚如雪逛腿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天仅颇,我揣著相機(jī)與錄音单默,去河邊找鬼。 笑死忘瓦,一個胖子當(dāng)著我的面吹牛搁廓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播耕皮,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼境蜕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了凌停?” 一聲冷哼從身側(cè)響起粱年,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎罚拟,沒想到半個月后台诗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赐俗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年拉队,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秃励。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡氏仗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出夺鲜,到底是詐尸還是另有隱情皆尔,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布币励,位于F島的核電站慷蠕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏食呻。R本人自食惡果不足惜流炕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一澎现、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧每辟,春花似錦剑辫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挠将,卻和暖如春胳岂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背舔稀。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工乳丰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人内贮。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓产园,卻偏偏與公主長得像,于是被迫代替她去往敵國和親夜郁。 傳聞我的和親對象是個殘疾皇子淆两,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

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