AFNetworking source code road

AFNetworkReachabilityManager

Manage the reachability of the network. When a network request fails, it can give a specific reason; when the network connection is established, it can trigger the specified network operation.

property

Initialization

+ sharedManager
+ manager
+ managerForDomain:
+ managerForAddress:
– initWithReachability:

sharedManager is a singleton and is implemented using dispatch_once in GCD:

+ (instancetype)sharedManager {
    static AFNetworkReachabilityManager *_sharedManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedManager = [self manager];
    });

    return _sharedManager;
}

dispatch_once:

        This function receives a special parameter of type dispatch_once_t, and a block parameter. For onceToken tokens, this function guarantees that the associated block will be executed and executed once. This operation is thread-safe. Note: For a block that is executed only once, the flag parameters passed to the function must be exactly the same. Therefore, when developing, you need to declare the flag variable as static or in the global scope.

        By designing singletons in this way, developers do not need to consider locking issues or thread synchronization issues, and all issues are handled at the bottom of GCD.

        dispatch_once uses "atomic access" to query tags to determine whether the code has been executed. 

Reference: blog

      

manager creates instance object

+ (instancetype)manager
{
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
    struct sockaddr_in6 address;//ipv6 type address structure
    bzero(&address, sizeof(address));
    address.sin6_len = sizeof(address);
    address.sin6_family = AF_INET6;
#else
    struct sockaddr_in address;//ipv4 type address structure
    bzero(&address, sizeof(address));
    address.sin_len = sizeof(address);
    address.sin_family = AF_INET;
#endif
    return [self managerForAddress:&address];
}

This method actually does some operations for variable initialization during socket communication: specifying the address type and protocol.

Then call the managerForAddress: method to create:

+ (instancetype)managerForAddress:(const void *)address {
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address);
    AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];

    CFRelease(reachability);
    
    return manager;
}

reachability is a structure of type SCNetworkReachabilityRef, where the address parameter is the address to be monitored.


Then call initWithReachability to create:

- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability {
    self = [super init];
    if (!self) {
        return nil;
    }

    _networkReachability = CFRetain(reachability);
    self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown;

    return self;
}

The reachability state is initialized to unknown.

Since SCNetworkReachabilityRef is an object in the Core Foundation framework, CFRetain is used for memory management.

managerForAddress is initialized by passing in an ip address of type sockaddr; because initWithReachability is called, CFRelease is required.

managerForDomain is initialized by passing in a domain name type ip address, such as " www.baidu.com "; also because initWithReachability is called, CFRelease is required.

[to be continued...]

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324580469&siteId=291194637