网络可达

+(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;

}

posted @ 2016-08-17 09:54  程石亮  阅读(383)  评论(0编辑  收藏  举报