网络可达
+(Reachability*)reachabilityWithHostname:(NSString*)hostname
{
SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);//通过主机名初始化网络可达对象
if (ref)
{
id reachability = [[self alloc] initWithReachabilityRef:ref];
return reachability;
}
return nil;
}
-(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref
{
self = [super init];
if (self != nil)
{
self.reachableOnWWAN = YES;
self.reachabilityRef = ref;//网络可达对象的持有化
self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL);//网络可达的操作队列
}
return self;
}
-(BOOL)startNotifier//添加监听网络变化的通知
{
if(self.reachabilityObject && (self.reachabilityObject == self))//已经添加了通知
{
return YES;
}
SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL };//初始化上下文
context.info = (__bridge void *)self; //当前对象保存到info中
if(SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context))//网络可达中设置了回调函数
{
if(SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue))
{
self.reachabilityObject = self;//托管当前的类,便于销毁该对象时不会导致当前类销毁
return YES;
}
else
{
#ifdef DEBUG
NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError()));
#endif
SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
}
}
else//网络可达中没有设置了回调函数
{
#ifdef DEBUG
NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError()));
#endif
}
self.reachabilityObject = nil;
return NO;
}
-(void)stopNotifier
{
SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);//移除网络可达通知中的上下文
SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL);//移除网络可达通知中的队列
self.reachabilityObject = nil;//销毁指向当前类的对象
}
-(BOOL)isReachableViaWWAN
{
#if TARGET_OS_IPHONE
SCNetworkReachabilityFlags flags = 0;
if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))//获取网络可达状态标志
{
if(flags & kSCNetworkReachabilityFlagsReachable)
{
if(flags & kSCNetworkReachabilityFlagsIsWWAN)//标志位是3G网络下
{
return YES;
}
}
}
#endif
return NO;
}