日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

初识Runloop

發(fā)布時間:2025/7/14 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 初识Runloop 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.runloop源碼

源碼

2.對象介紹

接下來的對象介紹,可以借助這個圖理清對象間的關(guān)系

// 一個runloop對象 typedef struct __CFRunLoop * CFRunLoopRef; // source typedef struct __CFRunLoopSource * CFRunLoopSourceRef; // observer觀察者 typedef struct __CFRunLoopObserver * CFRunLoopObserverRef; // timer typedef struct __CFRunLoopTimer * CFRunLoopTimerRef; // mode typedef struct __CFRunLoopMode *CFRunLoopModeRef;復(fù)制代碼

2.1. CFRunLoopRef

一個指向__CFRunLoop結(jié)構(gòu)體的指針

struct __CFRunLoop {CFRuntimeBase _base;pthread_mutex_t _lock; /* locked for accessing mode list */__CFPort _wakeUpPort; // used for CFRunLoopWakeUp Boolean _unused;volatile _per_run_data *_perRunData; // reset for runs of the run looppthread_t _pthread;uint32_t _winthread;CFMutableSetRef _commonModes;CFMutableSetRef _commonModeItems;CFRunLoopModeRef _currentMode;CFMutableSetRef _modes;struct _block_item *_blocks_head;struct _block_item *_blocks_tail;CFTypeRef _counterpart; }; 復(fù)制代碼

從這個結(jié)構(gòu)體的內(nèi)容可以看出:

  • 一個runloop對象主要包含modes、線程
  • modes是一個可變集合,里面存著mode,所以一個runloop對象可以包含多個mode
  • 一個 RunLoop 包含若干個 Mode,每個 Mode 又包含若干個 Source/Timer/Observer。(這三個的概念后面講)。每次調(diào)用 RunLoop 的主函數(shù)時,只能指定其中一個 Mode,這個Mode被稱作 CurrentMode。如果需要切換 Mode,只能退出 Loop,再重新指定一個 Mode 進入。這樣做主要是為了分隔開不同組的 Source/Timer/Observer,讓其互不影響。

2.2. CFRunLoopSourceRef

一個指向__CFRunLoopSource結(jié)構(gòu)體的指針

struct __CFRunLoopSource {CFRuntimeBase _base;uint32_t _bits;pthread_mutex_t _lock;CFIndex _order; /* immutable */CFMutableBagRef _runLoops;union {CFRunLoopSourceContext version0; /* immutable, except invalidation */CFRunLoopSourceContext1 version1; /* immutable, except invalidation */} _context; }; 復(fù)制代碼
  • 結(jié)構(gòu)體有一個_runLoops(可變包對象),說明一個source可以添加到多個runloop中

  • CFRunLoopSourceContext version0

typedef struct {CFIndex version;void * info;const void *(*retain)(const void *info);void (*release)(const void *info);CFStringRef (*copyDescription)(const void *info);Boolean (*equal)(const void *info1, const void *info2);CFHashCode (*hash)(const void *info);void (*schedule)(void *info, CFRunLoopRef rl, CFStringRef mode);void (*cancel)(void *info, CFRunLoopRef rl, CFStringRef mode);void (*perform)(void *info); } CFRunLoopSourceContext;復(fù)制代碼
  • CFRunLoopSourceContext1 version1
typedef struct {CFIndex version;void * info;const void *(*retain)(const void *info);void (*release)(const void *info);CFStringRef (*copyDescription)(const void *info);Boolean (*equal)(const void *info1, const void *info2);CFHashCode (*hash)(const void *info); #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)mach_port_t (*getPort)(void *info);void * (*perform)(void *msg, CFIndex size, CFAllocatorRef allocator, void *info); #elsevoid * (*getPort)(void *info);void (*perform)(void *info); #endif } CFRunLoopSourceContext1; 復(fù)制代碼
  • version0和version1區(qū)別 當(dāng)我們接受到的消息(source),比如觸摸事件,滑動事件等等;這個source是有兩種的,一種是version0,也就是用source0來表示,一種是version1 -> source1 區(qū)別
version0 / source0source0 是非基于 port 的事件,主要是 APP 內(nèi)部事件,如點擊事件,觸摸事件等
version1 / source1source1 是基于Port的,通過內(nèi)核和其他線程通信,接收,分發(fā)系統(tǒng)事件。

2.3. CFRunLoopObserverRef

一個指向__CFRunLoopObserver結(jié)構(gòu)體的指針 作用:觀察者,觀察runloop的各種狀態(tài),并通過回調(diào)拋出去

struct __CFRunLoopObserver {CFRuntimeBase _base;pthread_mutex_t _lock;CFRunLoopRef _runLoop;CFIndex _rlCount;CFOptionFlags _activities; /* immutable */CFIndex _order; /* immutable */CFRunLoopObserverCallBack _callout; /* immutable */CFRunLoopObserverContext _context; /* immutable, except invalidation */ }; 復(fù)制代碼

其中的CFOptionFlags是一個枚舉:表示runloop的狀態(tài)

/* Run Loop Observer Activities */ typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {kCFRunLoopEntry = (1UL << 0), // 即將進入loopkCFRunLoopBeforeTimers = (1UL << 1), // 即將處理timerkCFRunLoopBeforeSources = (1UL << 2), // 即將處理sourcekCFRunLoopBeforeWaiting = (1UL << 5), // 即將進入休眠kCFRunLoopAfterWaiting = (1UL << 6), // 剛從休眠中喚醒kCFRunLoopExit = (1UL << 7), // 即將退出loopkCFRunLoopAllActivities = 0x0FFFFFFFU // 占位 };復(fù)制代碼

CFRunLoopObserverRef觀察者會將觀察到的狀態(tài)變化通過回調(diào)_callout跑出去 看下這個CFRunLoopObserverCallBack _callout

// 這個回調(diào)可以將觀察者、runloop狀態(tài)、info傳出去 typedef void (*CFRunLoopObserverCallBack)(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info);復(fù)制代碼

2.4. CFRunLoopTimerRef

是一個指向__CFRunLoopTimer結(jié)構(gòu)體的指針

某些數(shù)據(jù)類型能夠在Core Foundation和Foundation之間互換使用,可被互換使用的數(shù)據(jù)類型被稱為Toll-Free Bridged類型。

  • CFRunLoopTimerRef 是定時器,可以在設(shè)定的時間點拋出回調(diào)
  • CFRunLoopTimerRef和NSTimer是toll-free bridged的,可以相互轉(zhuǎn)換。
struct __CFRunLoopTimer {CFRuntimeBase _base;uint16_t _bits;pthread_mutex_t _lock;CFRunLoopRef _runLoop;CFMutableSetRef _rlModes;CFAbsoluteTime _nextFireDate;CFTimeInterval _interval; /* immutable */CFTimeInterval _tolerance; /* mutable */uint64_t _fireTSR; /* TSR units */CFIndex _order; /* immutable */CFRunLoopTimerCallBack _callout; /* immutable */CFRunLoopTimerContext _context; /* immutable, except invalidation */ };復(fù)制代碼

2.5.CFRunLoopModeRef

一個指向__CFRunLoopMode結(jié)構(gòu)體的指針

typedef struct __CFRunLoopMode *CFRunLoopModeRef;struct __CFRunLoopMode {CFRuntimeBase _base;pthread_mutex_t _lock; /* must have the run loop locked before locking this */CFStringRef _name;Boolean _stopped;char _padding[3];CFMutableSetRef _sources0;CFMutableSetRef _sources1;CFMutableArrayRef _observers;CFMutableArrayRef _timers;CFMutableDictionaryRef _portToV1SourceMap;__CFPortSet _portSet;CFIndex _observerMask; #if USE_DISPATCH_SOURCE_FOR_TIMERSdispatch_source_t _timerSource;dispatch_queue_t _queue;Boolean _timerFired; // set to true by the source when a timer has firedBoolean _dispatchTimerArmed; #endif #if USE_MK_TIMER_TOOmach_port_t _timerPort;Boolean _mkTimerArmed; #endif #if DEPLOYMENT_TARGET_WINDOWSDWORD _msgQMask;void (*_msgPump)(void); #endifuint64_t _timerSoftDeadline; /* TSR */uint64_t _timerHardDeadline; /* TSR */ };復(fù)制代碼
  • _sources0、 _sources1都是可變集合對象,對應(yīng)著用來存取CFRunLoopSourceRef對象,CFRunLoopSourceRef對象中有version0、version1分別對應(yīng)著_sources0和_sources1
  • 包含了observer、timer
  • CFStringRef _name就是mode的名字,如:kCFRunLoopDefaultMode
  • 有幾種mode圖片來源

3.函數(shù)介紹

3.1.__CFRunLoopDoObservers

通知Observer,runloop要做什么事情 這個__CFRunLoopDoObservers函數(shù)需要傳三個參數(shù),分別是

  • CFRunLoopRef(runloop對象)
  • CFRunLoopModeRef(runloop的mode)
  • CFRunLoopActivity(runloop的狀態(tài)枚舉)

3.2._CFRunLoopGet0

runloop對象是存在全局字典中的,key就是pthread_t 這個_CFRunLoopGet0函數(shù)的作用就是獲取對應(yīng)線程的runloop

實現(xiàn)思路(依據(jù)就是下面截圖的源碼) 1.先判斷這個全局字典存不存在,不存在,創(chuàng)建一個,并將主線程的runloop加進去 2.直接去字典里取這個loop 3.如果loop不存在,就創(chuàng)建一個loop加入到全局字典中 // 偽代碼 if(!__CFRunLoops) {1.創(chuàng)建全局字典2.創(chuàng)建主線程loop,并加入到全局字典中 } 根據(jù)線程pthread_t為key,去字典取對應(yīng)的loop if(!loop) {1.創(chuàng)建loop2.加入到字典中 } return loop 復(fù)制代碼

其實這個說明了runloop和線程是一一對應(yīng)的關(guān)系

3.3.獲取主線程loop和獲取當(dāng)前的loop

參考文檔

強力推薦 RunLoop系列之要點提煉 RunLoop系列之源碼分析 iOS刨根問底-深入理解RunLoop 深入理解 RunLoop

總結(jié)

以上是生活随笔為你收集整理的初识Runloop的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。