YYKit源码探究(八十二) —— 网络相关YYReachability(一)

版本记录

版本号 时间
V1.0 2018.04.06

前言

iOS圈内有几个人大家基本都知道,比如说王巍、唐巧,还有YYKit框架的作者现任职于滴滴的郭曜源 - ibireme等。这里有一篇唐巧对他的专访,还有他的 GitHub - Yaoyuan博客,这里贴出来框架YYKit 框架。接下来几篇我们就一起来看一下这个框架。感兴趣的可以看上面写的几篇。
1. YYKit源码探究(一) —— 基本概览
2. YYKit源码探究(二) —— NSString分类之Hash(一)
3. YYKit源码探究(三) —— NSString分类之Encode and decode(二)
4. YYKit源码探究(四) —— NSString分类之Drawing(三)
5. YYKit源码探究(五) —— NSString分类之Regular Expression(四)
6. YYKit源码探究(六) —— NSString分类之NSNumber Compatible(五)
7. YYKit源码探究(七) —— NSString分类之Utilities(六)
8. YYKit源码探究(八) —— NSNumber分类(一)
9. YYKit源码探究(九) —— UIFont分类之架构分析和Font Traits(一)
10. YYKit源码探究(十) —— UIFont分类之Create font(二)
11. YYKit源码探究(十一) —— UIFont分类之Load and unload font(三)
12. YYKit源码探究(十二) —— UIFont分类之Dump font data(四)
13. YYKit源码探究(十三) —— UIImage分类之框架结构和Create image部分(一)
14. YYKit源码探究(十四) —— UIImage分类之Image Info(二)
15. YYKit源码探究(十五) —— UIImage分类之Modify Image(三)
16. YYKit源码探究(十六) —— UIImage分类之Image Effect(四)
17. YYKit源码探究(十七) —— UIImageView分类之架构和image部分(一)
18. YYKit源码探究(十八) —— UIImageView分类之highlight image部分(二)
19. YYKit源码探究(十九) —— UIScreen分类(一)
20. YYKit源码探究(二十) —— UIScrollView分类(一)
21. YYKit源码探究(二十一) —— UITableView分类(一)
22. YYKit源码探究(二十二) —— UITextField分类(一)
23. YYKit源码探究(二十三) —— UIView分类(一)
24. YYKit源码探究(二十四) —— UIPasteboard分类(一)
25. YYKit源码探究(二十五) —— UIGestureRecognizer分类(一)
26. YYKit源码探究(二十六) —— UIDevice分类框架及Device Information(一)
27. YYKit源码探究(二十七) —— UIDevice分类之Network Information(二)
28. YYKit源码探究(二十八) —— UIDevice分类之Disk Space(三)
29. YYKit源码探究(二十九) —— UIDevice分类之Memory Information(四)
30. YYKit源码探究(三十) —— UIDevice分类之CPU Information(五)
31. YYKit源码探究(三十一) —— UIControl分类(一)
32. YYKit源码探究(三十二) —— UIColor分类之Create a UIColor Object(一)
33. YYKit源码探究(三十三) —— UIColor分类之Get color's description(二)
34. YYKit源码探究(三十四) —— UIColor分类之Retrieving Color Information(三)
35. YYKit源码探究(三十五) —— UIButton分类之image(一)
36. YYKit源码探究(三十六) —— UIButton分类之background image(二)
37. YYKit源码探究(三十七) —— UIBezierPath分类(一)
38. YYKit源码探究(三十八) —— UIBarButtonItem分类(一)
39. YYKit源码探究(三十九) —— UIApplication分类(一)
40. YYKit源码探究(四十) —— NSTimer分类(一)
41. YYKit源码探究(四十一) —— NSParagraphStyle分类(一)
42. YYKit源码探究(四十二) —— NSObject分类之YYModel(一)
43. YYKit源码探究(四十三) —— NSObject分类之KVO(二)
44. YYKit源码探究(四十四) —— NSObject分类之Sending messages with variable parameters(三)
45. YYKit源码探究(四十五) —— NSObject分类之Swap method (Swizzling)(四)
46. YYKit源码探究(四十六) —— NSObject分类之Associate value(五)
47. YYKit源码探究(四十七) —— NSObject分类之Other(六)
48. YYKit源码探究(四十八) —— NSNotificationCenter分类(一)
49. YYKit源码探究(四十九) —— NSKeyedUnarchiver分类(一)
50. YYKit源码探究(五十) —— NSDictionary分类之Dictionary Convertor(一)
51. YYKit源码探究(五十一) —— NSDictionary分类之Dictionary Value Getter(二)
52. YYKit源码探究(五十二) —— NSDictionary分类之NSMutableDictionary(三)
53. YYKit源码探究(五十三) —— NSDate分类之Component Properties(一)
54. YYKit源码探究(五十四) —— NSDate分类之Date modify(二)
55. YYKit源码探究(五十五) —— NSDate分类之Date Format(三)
56. YYKit源码探究(五十六) —— NSData分类之Hash(一)
57. YYKit源码探究(五十七) —— NSData分类之Encrypt and Decrypt(二)
58. YYKit源码探究(五十八) —— NSData分类之Encode and decode(三)
59. YYKit源码探究(五十九) —— NSData分类之Inflate and deflate(四)
60. YYKit源码探究(六十) —— NSData分类之Others(五)
61. YYKit源码探究(六十一) —— NSBundle分类(一)
62. YYKit源码探究(六十二) —— NSAttributedString分类之基本(一)
63. YYKit源码探究(六十三) —— NSAttributedString分类之Retrieving character attribute information(二)
64. YYKit源码探究(六十四) —— NSAttributedString分类之Get character attribute as property(三)
65. YYKit源码探究(六十五) —— NSAttributedString分类之Get paragraph attribute as property(四)
66. YYKit源码探究(六十六) —— NSAttributedString分类之Get YYText attribute as property(五)
67. YYKit源码探究(六十七) —— NSAttributedString分类之Query for YYText(六)
68. YYKit源码探究(六十八) —— NSAttributedString分类之Create attachment string for YYText(七)
69. YYKit源码探究(六十九) —— NSAttributedString分类之Utility(八)
70. YYKit源码探究(七十) —— NSMutableAttributedString分类之Set character attribute(九)
71. YYKit源码探究(七十一) —— NSMutableAttributedString分类之Set character attribute as property(十)
72. YYKit源码探究(七十二) —— NSMutableAttributedString分类之Set paragraph attribute as property(十一)
73. YYKit源码探究(七十三) —— NSMutableAttributedString分类之Set YYText attribute as property(十二)
74. YYKit源码探究(七十四) —— NSMutableAttributedString分类之Set discontinuous attribute for range(十三)
75. YYKit源码探究(七十五) —— NSMutableAttributedString分类之Convenience methods for text highlight(十四)
76. YYKit源码探究(七十六) —— NSMutableAttributedString分类之Utilities(十五)
77. YYKit源码探究(七十七) —— NSArray分类(一)
78. YYKit源码探究(七十八) —— NSMutableArray分类(一)
79. YYKit源码探究(七十九) —— MKAnnotationView分类(一)
80. YYKit源码探究(八十) —— CALayer分类之YYWebImage(一)
81. YYKit源码探究(八十一) —— CALayer分类之YYAdd(二)

回顾

上一篇主要介绍了CALayer分类之YYAdd部分,这一篇主要看一下网络相关YYReachability部分。


API

下面我们就看一下API文档。

typedef NS_ENUM(NSUInteger, YYReachabilityStatus) {
    YYReachabilityStatusNone  = 0, ///< Not Reachable
    YYReachabilityStatusWWAN  = 1, ///< Reachable via WWAN (2G/3G/4G)
    YYReachabilityStatusWiFi  = 2, ///< Reachable via WiFi
};

typedef NS_ENUM(NSUInteger, YYReachabilityWWANStatus) {
    YYReachabilityWWANStatusNone  = 0, ///< Not Reachable vis WWAN
    YYReachabilityWWANStatus2G = 2, ///< Reachable via 2G (GPRS/EDGE)       10~100Kbps
    YYReachabilityWWANStatus3G = 3, ///< Reachable via 3G (WCDMA/HSDPA/...) 1~10Mbps
    YYReachabilityWWANStatus4G = 4, ///< Reachable via 4G (eHRPD/LTE)       100Mbps
};


/**
 `YYReachability` can used to monitor the network status of an iOS device.
 */
@interface YYReachability : NSObject

@property (nonatomic, readonly) SCNetworkReachabilityFlags flags;                           ///< Current flags.
@property (nonatomic, readonly) YYReachabilityStatus status;                                ///< Current status.
@property (nonatomic, readonly) YYReachabilityWWANStatus wwanStatus NS_AVAILABLE_IOS(7_0);  ///< Current WWAN status.
@property (nonatomic, readonly, getter=isReachable) BOOL reachable;                         ///< Current reachable status.

/// Notify block which will be called on main thread when network changed.
@property (nullable, nonatomic, copy) void (^notifyBlock)(YYReachability *reachability);

/// Create an object to check the reachability of the default route.
+ (instancetype)reachability;

/// Create an object to check the reachability of the local WI-FI.
+ (instancetype)reachabilityForLocalWifi DEPRECATED_MSG_ATTRIBUTE("unnecessary and potentially harmful");

/// Create an object to check the reachability of a given host name.
+ (nullable instancetype)reachabilityWithHostname:(NSString *)hostname;

/// Create an object to check the reachability of a given IP address
/// @param hostAddress You may pass `struct sockaddr_in` for IPv4 address or `struct sockaddr_in6` for IPv6 address.
+ (nullable instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress;

1. 两个枚举

这里涉及到两个枚举,一个用来区分WWAN和WIFI,另外一个用来区分WWAN内部的2G、3G、4G内部的网络类型。

typedef NS_ENUM(NSUInteger, YYReachabilityStatus) {
    YYReachabilityStatusNone  = 0, ///< Not Reachable
    YYReachabilityStatusWWAN  = 1, ///< Reachable via WWAN (2G/3G/4G)
    YYReachabilityStatusWiFi  = 2, ///< Reachable via WiFi
};

typedef NS_ENUM(NSUInteger, YYReachabilityWWANStatus) {
    YYReachabilityWWANStatusNone  = 0, ///< Not Reachable vis WWAN
    YYReachabilityWWANStatus2G = 2, ///< Reachable via 2G (GPRS/EDGE)       10~100Kbps
    YYReachabilityWWANStatus3G = 3, ///< Reachable via 3G (WCDMA/HSDPA/...) 1~10Mbps
    YYReachabilityWWANStatus4G = 4, ///< Reachable via 4G (eHRPD/LTE)       100Mbps
};

2. @property (nonatomic, readonly) SCNetworkReachabilityFlags flags;

这里用到了一个框架SystemConfiguration,这个枚举SCNetworkReachabilityFlags就在这个框架里面,这里引入头文件#import <SystemConfiguration/SystemConfiguration.h>

下面我们就看一下如何获取该属性的。

@property (nonatomic, assign) SCNetworkReachabilityRef ref;

- (SCNetworkReachabilityFlags)flags {
    SCNetworkReachabilityFlags flags = 0;
    SCNetworkReachabilityGetFlags(self.ref, &flags);
    return flags;
}

这里还涉及到SC框架中的一个函数:

/*!
    @function SCNetworkReachabilityGetFlags
    @discussion Determines if the given target is reachable using the
        current network configuration.
    @param target The network reference associated with the address or name
        to be checked for reachability.
    @param flags A pointer to memory that will be filled with the
        SCNetworkReachabilityFlags detailing the reachability
        of the specified target.
    @result Returns TRUE if the network connection flags are valid;
        FALSE if the status could not be determined.
 */
Boolean
SCNetworkReachabilityGetFlags           (
                        SCNetworkReachabilityRef    target,
                        SCNetworkReachabilityFlags  *flags
                        )               __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_2_0);

该函数的作用是,确定使用当前网络配置是否可以访问给定目标。

  • target:与地址或名称相关联的网络参考,以检查可达性。
  • flags:指向内存的指针,它将填充SCNetworkReachabilityFlags,详细说明指定目标的可达性。
  • return:如果网络连接标志有效,则为TRUE;如果无法确定状态,则为FALSE

这里还涉及到SC框架里的一个枚举值,下面一起看一下。

/*!
    @enum SCNetworkReachabilityFlags
    @discussion Flags that indicate whether the specified network
        nodename or address is reachable, whether a connection is
        required, and whether some user intervention may be required
        when establishing a connection.
    @constant kSCNetworkReachabilityFlagsTransientConnection
        This flag indicates that the specified nodename or address can
        be reached via a transient connection, such as PPP.
    @constant kSCNetworkReachabilityFlagsReachable
        This flag indicates that the specified nodename or address can
        be reached using the current network configuration.
    @constant kSCNetworkReachabilityFlagsConnectionRequired
        This flag indicates that the specified nodename or address can
        be reached using the current network configuration, but a
        connection must first be established.

        As an example, this status would be returned for a dialup
        connection that was not currently active, but could handle
        network traffic for the target system.
    @constant kSCNetworkReachabilityFlagsConnectionOnTraffic
        This flag indicates that the specified nodename or address can
        be reached using the current network configuration, but a
        connection must first be established.  Any traffic directed
        to the specified name or address will initiate the connection.

        Note: this flag was previously named kSCNetworkReachabilityFlagsConnectionAutomatic
    @constant kSCNetworkReachabilityFlagsInterventionRequired
        This flag indicates that the specified nodename or address can
        be reached using the current network configuration, but a
        connection must first be established.  In addition, some
        form of user intervention will be required to establish this
        connection, such as providing a password, an authentication
        token, etc.

        Note: At the present time, this flag will only be returned
        in the case where you have a dial-on-traffic configuration
        (ConnectionOnTraffic), where an attempt to connect has
        already been made, and where some error (e.g. no dial tone,
        no answer, bad password, ...) was encountered during the
        automatic connection attempt.  In this case the PPP controller
        will stop attempting to establish a connection until the user
        has intervened.
    @constant kSCNetworkReachabilityFlagsConnectionOnDemand
        This flag indicates that the specified nodename or address can
        be reached using the current network configuration, but a
        connection must first be established.
        The connection will be established "On Demand" by the
        CFSocketStream APIs.
        Other APIs will not establish the connection.
    @constant kSCNetworkReachabilityFlagsIsLocalAddress
        This flag indicates that the specified nodename or address
        is one associated with a network interface on the current
        system.
    @constant kSCNetworkReachabilityFlagsIsDirect
        This flag indicates that network traffic to the specified
        nodename or address will not go through a gateway, but is
        routed directly to one of the interfaces in the system.
#if TARGET_OS_IPHONE
    @constant kSCNetworkReachabilityFlagsIsWWAN
        This flag indicates that the specified nodename or address can
        be reached via an EDGE, GPRS, or other "cell" connection.
#endif  // TARGET_OS_IPHONE
 */
typedef CF_OPTIONS(uint32_t, SCNetworkReachabilityFlags) {
    kSCNetworkReachabilityFlagsTransientConnection  = 1<<0,
    kSCNetworkReachabilityFlagsReachable        = 1<<1,
    kSCNetworkReachabilityFlagsConnectionRequired   = 1<<2,
    kSCNetworkReachabilityFlagsConnectionOnTraffic  = 1<<3,
    kSCNetworkReachabilityFlagsInterventionRequired = 1<<4,
    kSCNetworkReachabilityFlagsConnectionOnDemand   = 1<<5, // __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_0)
    kSCNetworkReachabilityFlagsIsLocalAddress   = 1<<16,
    kSCNetworkReachabilityFlagsIsDirect     = 1<<17,
#if TARGET_OS_IPHONE
    kSCNetworkReachabilityFlagsIsWWAN       = 1<<18,
#endif  // TARGET_OS_IPHONE

    kSCNetworkReachabilityFlagsConnectionAutomatic  = kSCNetworkReachabilityFlagsConnectionOnTraffic
};

这里和大家一起看一下:

指示指定的网络节点名称或地址是否可达,是否需要连接以及建立连接时是否需要某些用户干预的标志。

  • kSCNetworkReachabilityFlagsTransientConnection

    • 该标志表示可以通过临时连接(如PPP)访问指定的节点名称或地址。
  • kSCNetworkReachabilityFlagsReachable

    • 该标志表示可以使用当前的网络配置来访问指定的节点名称或地址。
  • kSCNetworkReachabilityFlagsConnectionRequired

    • 该标志表示可以使用当前网络配置访问指定的节点名称或地址,但必须首先建立连接。作为一个例子,这个状态将返回一个当前不活动的拨号连接,但可以处理目标系统的网络流量。
  • kSCNetworkReachabilityFlagsConnectionOnTraffic

    • 该标志表示可以使用当前网络配置访问指定的节点名称或地址,但必须首先建立连接。 任何指向指定名称或地址的流量都将启动连接。 注意:此标志以前名为kSCNetworkReachabilityFlagsConnectionAutomatic
  • kSCNetworkReachabilityFlagsInterventionRequired

    • 此标志表示可以使用当前网络配置来访问指定的节点名称或地址,但是另外需要某种形式的用户干预来建立此连接,例如提供密码,身份验证令牌等。注意:目前这个标志只会出现在你有拨号流量配置(ConnectionOnTraffic)的情况下,在这种情况下,已经进行了连接尝试,并且出现了一些错误(例如没有拨号音,没有应答,坏的密码,...)在自动连接尝试期间遇到。 在这种情况下,PPP控制器将停止尝试建立连接,直到用户干预。
  • kSCNetworkReachabilityFlagsConnectionOnDemand

    • 该标志表示可以使用当前的网络配置访问指定的节点名或地址,但必须首先建立连接。连接将由CFSocketStream API“按需”建立。 其他API不会建立连接。
  • kSCNetworkReachabilityFlagsIsLocalAddress

    • 该标志表示指定的节点名称或地址是与当前系统上的网络接口关联的节点名称或地址。
  • kSCNetworkReachabilityFlagsIsDirect

    • 此标志表示到指定节点名称或地址的网络流量不会通过网关,而是直接路由到系统中的某个接口。
  • kSCNetworkReachabilityFlagsIsWWAN

    • 该标志表示可以通过EDGEGPRS或其他“cell”连接到达指定的节点名称或地址。

3. @property (nonatomic, readonly) YYReachabilityStatus status;

这个枚举值的定义就是用来区分WWANWIFI的。下面我们就看一下这个只读属性的获取。

方法实现

- (YYReachabilityStatus)status {
    return YYReachabilityStatusFromFlags(self.flags, self.allowWWAN);
}

这里用到了一个函数:

static YYReachabilityStatus YYReachabilityStatusFromFlags(SCNetworkReachabilityFlags flags, BOOL allowWWAN) {
    if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) {
        return YYReachabilityStatusNone;
    }
    
    if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
        (flags & kSCNetworkReachabilityFlagsTransientConnection)) {
        return YYReachabilityStatusNone;
    }
    
    if ((flags & kSCNetworkReachabilityFlagsIsWWAN) && allowWWAN) {
        return YYReachabilityStatusWWAN;
    }
    
    return YYReachabilityStatusWiFi;
}

这个函数的作用就是返回指定的网络类型,WWANWIFI或者None状态。

4. @property (nonatomic, readonly) YYReachabilityWWANStatus wwanStatus

该属性的作用就是获取该网络是2G、3G还是4G,或者是位置状态。

方法实现

- (YYReachabilityWWANStatus)wwanStatus {
    if (!self.networkInfo) return YYReachabilityWWANStatusNone;
    NSString *status = self.networkInfo.currentRadioAccessTechnology;
    if (!status) return YYReachabilityWWANStatusNone;
    static NSDictionary *dic;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dic = @{CTRadioAccessTechnologyGPRS : @(YYReachabilityWWANStatus2G),  // 2.5G   171Kbps
                CTRadioAccessTechnologyEdge : @(YYReachabilityWWANStatus2G),  // 2.75G  384Kbps
                CTRadioAccessTechnologyWCDMA : @(YYReachabilityWWANStatus3G), // 3G     3.6Mbps/384Kbps
                CTRadioAccessTechnologyHSDPA : @(YYReachabilityWWANStatus3G), // 3.5G   14.4Mbps/384Kbps
                CTRadioAccessTechnologyHSUPA : @(YYReachabilityWWANStatus3G), // 3.75G  14.4Mbps/5.76Mbps
                CTRadioAccessTechnologyCDMA1x : @(YYReachabilityWWANStatus3G), // 2.5G
                CTRadioAccessTechnologyCDMAEVDORev0 : @(YYReachabilityWWANStatus3G),
                CTRadioAccessTechnologyCDMAEVDORevA : @(YYReachabilityWWANStatus3G),
                CTRadioAccessTechnologyCDMAEVDORevB : @(YYReachabilityWWANStatus3G),
                CTRadioAccessTechnologyeHRPD : @(YYReachabilityWWANStatus3G),
                CTRadioAccessTechnologyLTE : @(YYReachabilityWWANStatus4G)}; // LTE:3.9G 150M/75M  LTE-Advanced:4G 300M/150M
    });
    NSNumber *num = dic[status];
    if (num) return num.unsignedIntegerValue;
    else return YYReachabilityWWANStatusNone;
}

5. @property (nonatomic, readonly, getter=isReachable) BOOL reachable;

这个属性就是直接判断网络是否可达。

方法实现

- (BOOL)isReachable {
    return self.status != YYReachabilityStatusNone;
}

 (YYReachabilityStatus)status {
    return YYReachabilityStatusFromFlags(self.flags, self.allowWWAN);
}

6. @property (nullable, nonatomic, copy) void (^notifyBlock)(YYReachability *reachability);

该属性的作用就是当网络状态发生变化后,就会在主线程通过block进行回调。

下面看一下实现

方法实现

- (void)setNotifyBlock:(void (^)(YYReachability *reachability))notifyBlock {
    _notifyBlock = [notifyBlock copy];
    self.scheduled = (self.notifyBlock != nil);
}

- (void)setScheduled:(BOOL)scheduled {
    if (_scheduled == scheduled) return;
    _scheduled = scheduled;
    if (scheduled) {
        SCNetworkReachabilityContext context = { 0, (__bridge void *)self, NULL, NULL, NULL };
        SCNetworkReachabilitySetCallback(self.ref, YYReachabilityCallback, &context);
        SCNetworkReachabilitySetDispatchQueue(self.ref, [self.class sharedQueue]);
    } else {
        SCNetworkReachabilitySetDispatchQueue(self.ref, NULL);
    }
}

static void YYReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info) {
    YYReachability *self = ((__bridge YYReachability *)info);
    if (self.notifyBlock) {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.notifyBlock(self);
        });
    }
}

7. + (instancetype)reachability;

该方法的作用就是监测默认路由的可达性。

方法实现

+ (instancetype)reachability {
    return self.new;
}

8. + (instancetype)reachabilityForLocalWifi DEPRECATED_MSG_ATTRIBUTE("unnecessary and potentially harmful");

用来检测WIFI的可达性。

方法实现

+ (instancetype)reachabilityForLocalWifi {
    struct sockaddr_in localWifiAddress;
    bzero(&localWifiAddress, sizeof(localWifiAddress));
    localWifiAddress.sin_len = sizeof(localWifiAddress);
    localWifiAddress.sin_family = AF_INET;
    localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
    YYReachability *one = [self reachabilityWithAddress:(const struct sockaddr *)&localWifiAddress];
    one.allowWWAN = NO;
    return one;
}

9. + (nullable instancetype)reachabilityWithHostname:(NSString *)hostname;

用来判断给定host的可达性。

方法实现

+ (instancetype)reachabilityWithHostname:(NSString *)hostname {
    SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);
    return [[self alloc] initWithRef:ref];
}

- (instancetype)initWithRef:(SCNetworkReachabilityRef)ref {
    if (!ref) return nil;
    self = super.init;
    if (!self) return nil;
    _ref = ref;
    _allowWWAN = YES;
    if (NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0) {
        _networkInfo = [CTTelephonyNetworkInfo new];
    }
    return self;
}

10. + (nullable instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress;

该方法的作用就是判断给定IP地址的可达性,下面看一下方法实现。

方法实现

+ (instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress {
    SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)hostAddress);
    return [[self alloc] initWithRef:ref];
}

后记

本篇主要介绍了网络相关的内容,感兴趣的给个赞或者关注~~~

推荐阅读更多精彩内容