SCNetworkReachabilityRef
接口可以確定當前主機的網(wǎng)絡狀態(tài)以及目標主機的可達性, 可達性是指data packet(數(shù)據(jù)包)可以從當前主機發(fā)送出去, 而不是目標主機可以接收到data packet(數(shù)據(jù)包).
SCNetworkReachabilityRef
接口有同步和異步兩種模式.
在同步模式下, 可以通過SCNetworkReachabilityGetFlags
方法獲取網(wǎng)絡狀態(tài);
在異步模式下, 可以調(diào)度一個SCNetworkReachability
對象到客戶端的運行循環(huán)上, 客戶端實現(xiàn)一個回調(diào)函數(shù)接收網(wǎng)絡狀態(tài)變化的通知, 這個回調(diào)函數(shù)遵循Core Foundation
命名規(guī)范, 只要函數(shù)名中包含 "Create" 或 "Copy"的函數(shù)返回的引用,都必須調(diào)用CFRelease來釋放。
SCNetworkReachabilityRef
中幾個主要的方法和屬性:
SCNetworkReachabilityContext結(jié)構(gòu)體
typedef struct {
CFIndex version;
void * __nullable info;
const void * __nonnull (* __nullable retain)(const void *info);
void (* __nullable release)(const void *info);
CFStringRef __nonnull (* __nullable copyDescription)(const void *info);
} SCNetworkReachabilityContext;
結(jié)構(gòu)體中包含用戶指定的數(shù)據(jù)信息和用于SCNetworkReachabilitySetCallback
方法的回調(diào)info
.
version
為版本號, 作為參數(shù)傳遞給SCDynamicStore
創(chuàng)建結(jié)構(gòu)體類型的版本號. 這個結(jié)構(gòu)體的版本號為0.
info
是一個C語言的指針對象, 這里一般傳入當網(wǎng)絡狀態(tài)發(fā)生改變時執(zhí)行的block
回調(diào), 個人理解為C語言的指針不在ARC
的管理范圍內(nèi), 需要手動管理內(nèi)存, 所以這里傳入release info
和retain info
用于管理內(nèi)存.
這個結(jié)構(gòu)體需要在SCNetworkReachabilitySetCallback
設置才能起作用.
創(chuàng)建網(wǎng)絡連接引用
SCNetworkReachabilityRef SCNetworkReachabilityCreateWithAddress(CFAllocatorRef allocator, const struct sockaddr *address);
通過傳入需要測試的IP地址創(chuàng)建網(wǎng)絡連接引用, allocator
可以設置為NULL
或者kCFAllocatorDefault
.
SCNetworkReachabilityRef SCNetworkReachabilityCreateWithName(CFAllocatorRef allocator, const char *nodename);
通過傳入需要測試的網(wǎng)址創(chuàng)建網(wǎng)絡連接引用, 同上個方法.
獲取網(wǎng)絡連接狀態(tài)
Boolean SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags);
用于獲取網(wǎng)絡連接的狀態(tài), 傳入的第一個參數(shù)是SCNetworkReachabilityRef
網(wǎng)絡連接引用, 第二個參數(shù)用來保存獲取的網(wǎng)絡連接狀態(tài), 如果能獲取到連接就返回true
否則返回false
.
網(wǎng)絡狀態(tài)改變時的通知
Boolean SCNetworkReachabilitySetCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityCallBack callout, SCNetworkReachabilityContext *context);
當網(wǎng)絡狀態(tài)發(fā)生變化時, 就會調(diào)用callout
, 第一個參數(shù)是網(wǎng)絡連接引用, 第二個參數(shù)是回調(diào), 如果為NULL
, 當前的target
就會被移除, SCNetworkReachabilityCallBack
的類型為(typedef void (*SCNetworkReachabilityCallBack)(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info);) callout回調(diào)中的info
參數(shù)就是從第三個參數(shù)context結(jié)構(gòu)體中取的info
回調(diào), 這樣就把結(jié)構(gòu)體context
中的數(shù)據(jù)傳到了SCNetworkReachabilityCallBack
參數(shù)中, 第三個參數(shù)是與callout
相關(guān)聯(lián)的上下文, 可能為空. 如果通知客戶端成功就返回true
, 否則返回false
.
Boolean SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef target, CFRunLoopRef runLoop, CFStringRef runLoopMode);
使用指定的運行循環(huán)和模式調(diào)度指定的網(wǎng)絡目標, 第一個參數(shù)是網(wǎng)絡連接引用, 第二個參數(shù)runloop
循環(huán), 第三個參數(shù)循環(huán)模式. 如果target
運行成功就返回true
, 否則返回false
.
這里將target
加入指定的runloop
中, 會一直監(jiān)測target
的網(wǎng)絡狀態(tài), 當網(wǎng)絡狀態(tài)發(fā)生變化時就會執(zhí)行SCNetworkReachabilitySetCallback
方法中的callout
回調(diào), 所以我們只需要定義一個SCNetworkReachabilityCallBack
類型的block
, 將其傳入SCNetworkReachabilitySetCallback
方法中即可.