亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

iOS開發日記24-RunLoop終極篇

2019-11-14 18:16:21
字體:
來源:轉載
供稿:網友

今天博主有一個RunLoop的需求,遇到了一些困難點,在此和大家分享,希望能夠共同進步.

RunLoop是什么?

從字面上理解,Runloop指的就是運行循環,iOS中,只要程序啟動, 就會創建Runloop,用來處理各種事件(比如定時器事件, 觸摸事件等).

它的主要作用有以下幾個:

1.保持程序的運行:如果沒有它, 程序一啟動就over了;

2.事件的處理: 包括按鈕點擊事件, 屏幕的點擊事件等;

3.定時器處理: NSTimer的處理;

4.節約CPU, 提高性能:有任務的時候干活,沒有任務時候休息.

在iOS中, 可以通過兩套API來訪問Runloop:

1.Foundation框架: OC中的框架, 直接訪問NSRunLoop對象.

2.Core Foundation框架: c語言的框架, 通過CFRunLooPRef訪問.

實際上, NSRunLoop和CFRunLoopRef是同一個對象, 只不過通過不同的API來訪問的,NSRunLoop是對CFRunLoopRef的封裝.

 

OC中, 使用下面代碼就可以獲得Runloop對象:

// Foundation

[NSRunLoop currentRunLoop]; // 獲得當前線程的RunLoop對象

[NSRunLoop mainRunLoop]; // 獲得主線程的RunLoop對象

// Core Foundation

CFRunLoopGetCurrent(); // 獲得當前線程的RunLoop對象

CFRunLoopGetMain(); // 獲得主線程的RunLoop對象

 

Nslog打印Runloop對象, 里面的內容如下:(由于內容比較多, 只將重點內容列出)

 // runloop對象 <CFRunLoop 0x7fb13172abc0 [0x10a5aa180]>{wakeup port = 0x1003, stopped = false, ignoreWakeUps = true,// 當前模式current mode = UIInitializationRunLoopMode,common modes = <CFBasicHash 0x7fb13172ac80// common modes標記了哪兩個模式(后面會講為啥是標記?)    0 : <CFString 0x10b27ce50 [0x10a5aa180]>{contents = "UITrackingRunLoopMode"}    2 : <CFString 0x10a586080 [0x10a5aa180]>{contents = "kCFRunLoopDefaultMode"}}// source: 源6 : <CFRunLoopSource 0x7fb131415300 [0x10a5aa180]>// observers: 觀察者observers = <CFArray 0x7fb13141d300 [0x10a5aa180]>// timer: 定時器timers = (null),// 兩種不同的模式3 : <CFRunLoopMode 0x7fb13172dbb0 [0x10a5aa180]>{name = GSEventReceiveRunLoopMode, port set = 0x2003, timer port = 0x2103,    sources0 = <CFBasicHash 0x7fb13172d260 [0x10a5aa180]>{type = mutable set, count = 1,entries =>    0 : <CFRunLoopSource 0x7fb13172da30 [0x10a5aa180]>{signalled = No, valid = Yes, order = -1, context = <CFRunLoopSource context>{version = 0, info = 0x0, callout = PurpleEventSignalCallback (0x10d8236c8)}}}

要想知道上面內容是什么意思, 先看下面的內容:

Core Foundation中關于RunLoop的5個類1.CFRunLoopRef2.CFRunLoopModeRef3.CFRunLoopSourceRef4.CFRunLoopTimerRef5.CFRunLoopObserverRef
可以這理解為, 一個Runloop對象里面, 必不可少的是CFRunLoopModeRef, Mode里面可以包含timer/source/oberver(只有包含了其中一個, Runloop才能在啟動后保證不死)

層級結構如下圖:

接下來, 對里面的內容說明一下:

一.CFRunLoopModeRef:代表RunLoop的運行模式    1.一個RunLoop包含若干個Mode,每個Mode又包含若干個Source/Timer/Observer    2.每次RunLoop啟動時,只能指定其中一個 Mode,這個Mode被稱作CurrentMode    3.這樣做主要是為了分隔開不同組的Source/Timer/Observer,讓其互不影響系統默認注冊了5個Mode:    1.kCFRunLoopDefaultMode:App的默認Mode,通常主線程是在這個Mode下運行    2.UITrackingRunLoopMode:界面跟蹤 Mode,用于 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其他 Mode 影響    3.UIInitializationRunLoopMode: 在剛啟動 App 時第進入的第一個 Mode,啟動完成后就不再使用    4.GSEventReceiveRunLoopMode: 接受系統事件的內部 Mode,通常用不到    5.kCFRunLoopCommonModes: 這是一個占位用的Mode,不是一種真正的Mode, 被標記為kCFRunLoopCommonModes格式的都可以成為commonMode, 其中包含1.2兩種模式.二.CFRunLoopSourceRef:是事件源(輸入源)    現在主要分為兩種:    Source0:非基于Port的    Source1:基于Port的(如GCD底層實現也是通過Port的, 主要用于線程之間的通信)三.CFRunLoopTimerRef:是基于時間的觸發器, 基本上說的就是NSTimer四.CFRunLoopObserverRef:觀察者, 可以用來監聽Runloop的狀態, 下面列出了Runloop的狀態typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {    kCFRunLoopEntry = (1UL << 0), // 即將進入    kCFRunLoopBeforeTimers = (1UL << 1), // 即將處理timer    kCFRunLoopBeforeSources = (1UL << 2), // 即將處理事件源    kCFRunLoopBeforeWaiting = (1UL << 5), // 即將進入休眠    kCFRunLoopAfterWaiting = (1UL << 6), // 剛從休眠中喚醒    kCFRunLoopExit = (1UL << 7), // 即將退出Runloop};

下面圖片描述了Runloop的運行和狀態:

Runloop的寄生于線程:一個線程只能有唯一對應的runloop;但這個根runloop里可以嵌套子runloops;
自動釋放池寄生于Runloop:程序啟動后,主線程注冊了兩個Observer監聽runloop的進出與睡覺。一個最高優先級OB監測Entry狀態;一個最低優先級OB監聽BeforeWaiting狀態和Exit狀態。
線程(創建)-->runloop將進入-->最高優先級OB創建釋放池-->runloop將睡-->最低優先級OB銷毀舊池創建新池-->runloop將退出-->最低優先級OB銷毀新池-->線程(銷毀)

Mach是XNU的內核,進程、線程和虛擬內存等對象通過端口發消息進行通信,Runloop通過mach_msg()函數發送消息,如果沒有port 消息,內核會將線程置于等待狀態 mach_msg_trap() 。如果有消息,判斷消息類型處理事件,并通過modeItem的callback回調。

Runloop有兩個關鍵判斷點,一個是通過msg決定Runloop是否等待,一個是通過判斷退出條件來決定Runloop是否循環。

 

應用1:滑動與圖片刷新:

當tableview的cell上有需要從網絡獲取的圖片的時候,滾動tableView,異步線程會去加載圖片,加載完成后主線程就會設置cell的圖片,但是會造成卡頓??梢宰屧O置圖片的任務在CFRunLoopDefaultMode下進行,當滾動tableView的時候,RunLoop是在 UITrackingRunLoopMode 下進行,不去設置圖片,而是當停止的時候,再去設置圖片。

- (void)viewDidLoad { 

[super viewDidLoad];  // 只在NSDefaultRunLoopMode下執行(刷新圖片) 

[self.myImageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@""] afterDelay:ti inModes:@[NSDefaultRunLoopMode]];  

 }

應用2:常駐子線程,保持子線程一直處理事件
為了保證線程長期運轉,可以在子線程中加入RunLoop,并且給Runloop設置item,防止Runloop自動退出。

+ (void)networkRequestThreadEntryPoint:(id)__unused object {    @autoreleasepool {        [[NSThread currentThread] setName:@"AFNetworking"];        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];        [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];        [runLoop run];    }}+ (NSThread *)networkRequestThread {    static NSThread *_networkRequestThread = nil;    static dispatch_once_t oncePredicate;    dispatch_once(&oncePredicate, ^{        _networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil];        [_networkRequestThread start];    });    return _networkRequestThread;}- (void)start {    [self.lock lock];    if ([self isCancelled]) {        [self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];    } else if ([self isReady]) {        self.state = AFOperationExecutingState;        [self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];    }    [self.lock unlock];}


http://www.49028c.com/66it/p/4719701.html?utm_source=tuicool
http://blog.ibireme.com/2015/05/18/runloop/

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久视频精品| 久久影院资源站| 久久精品成人欧美大片| 国产男人精品视频| 日韩视频免费大全中文字幕| 欧美一级bbbbb性bbbb喷潮片| 久久精品在线播放| 亚洲精选一区二区| 91福利视频网| 亚洲天堂第二页| 久久久久久国产免费| 欧美韩日一区二区| 国产精品久久久久久中文字| 欧美日韩国产中文字幕| 亚洲欧洲在线视频| 国产日韩欧美电影在线观看| 国产99视频在线观看| www.亚洲男人天堂| 国产成人一区二区三区电影| 色综合久久天天综线观看| 久久成人国产精品| 亚洲成人a**站| 国产精品极品美女在线观看免费| 精品无码久久久久久国产| 国产精品久久久久秋霞鲁丝| 伊人久久综合97精品| 日韩国产在线看| 亚洲精品99久久久久中文字幕| 亚洲成人av片| 久久成人综合视频| 日韩中文字幕在线精品| 97视频人免费观看| 日产日韩在线亚洲欧美| 国产精品电影观看| 这里只有精品久久| 精品国产一区二区三区四区在线观看| 夜夜嗨av一区二区三区免费区| 成人写真福利网| 成人在线国产精品| 久久久国产一区二区| 原创国产精品91| 欧美三级欧美成人高清www| 综合国产在线观看| 伊人久久免费视频| 亚洲天堂免费视频| 97碰碰碰免费色视频| 日韩视频欧美视频| 最近2019年手机中文字幕| 亚洲一区二区三区乱码aⅴ| 国产成人在线亚洲欧美| 97精品久久久中文字幕免费| 亚洲精品国产品国语在线| 亚洲jizzjizz日本少妇| 久久高清视频免费| 欧美视频在线观看免费| 中文字幕综合一区| 日韩美女中文字幕| 欧美激情国产高清| 另类图片亚洲另类| 国产精品欧美日韩久久| 色婷婷综合久久久久中文字幕1| 欧美极品第一页| 91av中文字幕| 成人xxxxx| 7777kkkk成人观看| 日韩在线观看成人| 亚洲成色999久久网站| 日本一区二区在线播放| 久久99精品国产99久久6尤物| 亚洲第一天堂无码专区| 永久免费精品影视网站| 亚洲第一黄色网| 国产成人在线播放| 久久精品免费电影| 欧美性猛交视频| 亚洲免费电影在线观看| 中文字幕在线看视频国产欧美在线看完整| 国产成人小视频在线观看| 日韩黄色在线免费观看| 一区二区亚洲精品国产| 国产在线视频一区| 琪琪亚洲精品午夜在线| 午夜剧场成人观在线视频免费观看| 久久激情视频久久| 97视频在线播放| 日本在线精品视频| 激情懂色av一区av二区av| 欧美大胆a视频| 欧美午夜丰满在线18影院| 日韩精品免费视频| 91性高湖久久久久久久久_久久99| 伊人一区二区三区久久精品| 播播国产欧美激情| 一区二区三区在线播放欧美| 欧美日本国产在线| 伊人伊人伊人久久| 欧美与欧洲交xxxx免费观看| 亚洲美女视频网站| 91午夜在线播放| 日韩欧美在线视频观看| 国产aaa精品| 大荫蒂欧美视频另类xxxx| 国产一区av在线| 亚洲欧美视频在线| 欧美日韩999| 欧美日韩中文字幕综合视频| 国产一区二区三区丝袜| 亚洲欧美国产视频| 国内精品在线一区| 成人激情在线观看| 国产精品美女www| 日本免费久久高清视频| 色综合久综合久久综合久鬼88| 伊人精品在线观看| 国产日韩av在线| 日韩高清中文字幕| 欧美激情奇米色| 成人网页在线免费观看| 亚洲一级免费视频| 国产视频欧美视频| 国产91精品久久久久久| 欧美日韩xxx| 欧美亚洲在线播放| 久久人人爽国产| 欧美黑人xxxx| 成人免费激情视频| 中文字幕欧美日韩| 亚洲欧美国产一区二区三区| 国产精品久久久久久久久久| 久久99青青精品免费观看| 97精品国产97久久久久久免费| 日韩国产中文字幕| 亚洲精品v欧美精品v日韩精品| 亚洲xxxx3d| 日韩电影在线观看永久视频免费网站| 精品国产区一区二区三区在线观看| 国产国语刺激对白av不卡| 亚洲香蕉成视频在线观看| 国产精品色悠悠| 亚洲第一天堂av| 欧美在线播放视频| 午夜精品久久久久久久久久久久久| 久久久久久尹人网香蕉| 欧美精品日韩www.p站| 亚洲性日韩精品一区二区| 国产综合在线观看视频| 久久精品电影网| 亚洲第一男人av| 成人免费在线视频网址| 亚洲电影成人av99爱色| 成人国产在线激情| 久久亚洲私人国产精品va| 国产性色av一区二区| 久久久久久久久久久亚洲| 国内揄拍国内精品| 国产亚洲精品久久久久动| 欧美精品亚州精品| 日韩成人xxxx| 亚洲在线观看视频| 81精品国产乱码久久久久久| 26uuu国产精品视频| 成人乱人伦精品视频在线观看| 青青a在线精品免费观看| 97**国产露脸精品国产|