可达性崩溃应用程式 [英] Reachability crashes app

查看:404
本文介绍了可达性崩溃应用程式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚实现了苹果的Reachability代码,我的应用程序现在崩溃了一个完全不一致和随机的方式:它可以成功加载20个网页连续 - 但随后在21日崩溃。尝试,或者它可能崩溃后只是第二。网页加载尝试



Instruments / NSZombies显示出一些奇怪的地方:RefCt高达20(!),Responsible Callers是几个不同的:[UIRuntimeConnection initWithCoder],[UINib instantiateWithOwner:options],[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]等。
是否正常?



最后一个负责人?
这些是[UIWindowController transitionViewDidComplete:fromView:toView:](它使RefCt为0)和
[UIWebView webView:didFinishLoadForFrame:](它将RefCt降低到-1)?



如何进行调试和解决?



这是代码:

  #importReachability.h


- (void)viewWillAppear:(BOOL)animated
{
//检查互联网连接
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus :) name:kReachabilityChangedNotification object:nil];

internetReachable = [[Reachability reachabilityForInternetConnection] retain];
[internetReachable startNotifier];

//检查是否存在到随机主机的路径
hostReachable = [[Reachability reachabilityWithHostName:@www.apple.com] retain];
[hostReachable startNotifier];

//现在耐心等待通知
}



- (void)viewDidLoad {

url = [NSURL URLWithString:@http://www.google.com];
NSURLRequest * req = [NSURLRequest requestWithURL:url];
[webPageView loadRequest:req];
[super viewDidLoad];
}



- (void)checkNetworkStatus:(NSNotification *)notice
{
//网络状态更改后调用

NetworkStatus InternetStatus = [internetReachable currentReachabilityStatus];

switch(internetStatus)
{
case NotReachable:
{
// NSLog(@互联网已关闭。
//self.internetActive = NO; //(这是一个BOOL变量)
[self displayMessageWithTitle:@ERROR
andMessage:@无法连接到Internet
andOKButton:@OK
[self dismissModalViewControllerAnimated:YES];
break;

}
case ReachableViaWiFi:
{
// NSLog(@互联网是通过WIFI工作。
//self.internetActive = YES; //

break;

}
case ReachableViaWWAN:
{
// NSLog(@互联网正在通过WWAN工作。
// self.internetActive = YES; //(这是一个BOOL变量)

break;

}
}

NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
switch(hostStatus)
{
case NotReachable:
{
// NSLog(@到主机服务器的网关关闭。
// self.hostActive = NO; //(这是一个BOOL变量)

[self displayMessageWithTitle:@ERROR
andMessage:@Host Not Reachable
andOKButton:@OK
[self dismissModalViewControllerAnimated:YES];
break;

}

case ReachableViaWiFi:
{
// NSLog(@主机服务器的网关通过WIFI工作。
//self.hostActive = YES; //(这是一个BOOL变量)

break;

}

case ReachableViaWWAN:
{
// NSLog(@主机服务器的网关通过WWAN工作。
// self.hostActive = YES; //(这是一个BOOL变量)

break;

}
}
}



- (void)webViewDidStartLoad:(UIWebView *)webView {
[activityIndi​​cator startAnimating];
}


- (void)webViewDidFinishLoad:(UIWebView *)webView {
[activityIndi​​cator stopAnimating];
}


//因为这个ViewController是以Modally方式显示的,所以这个方法删除它:
- (IBAction)dismissWebTixView:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}




- (void)viewWillDisappear:(BOOL)animated {
NSLog(@在webForTix的'viewWillDisappear' ....);
[[NSNotificationCenter defaultCenter] deleteObserver:self
name:kReachabilityChangedNotification
object:nil];
}


//读取某个地方,最好放在removeObserver
//调用这里,而不是viewWillDisappear ...试过两个 - 仍然收到崩溃....
- (void)dealloc
{
// NSLog(@In webForTix's dealloc method ....);
// [[NSNotificationCenter defaultCenter] removeObserver:self
// name:kReachabilityChangedNotification
// object:nil];
NSLog(@在webForTix的dealloc方法 - removedObserver ...);
[super dealloc];

}

解决方案<



从开发人员苹果到您的项目包含Reachability.h和Reachability.m文件。从SDK库导入SystemConfiguration框架到您的项目。然后添加以下GlobalFunction.h和GlobalFunction.m文件到您的项目

  // GlobalFunction.h 


#import< Foundation / Foundation.h>

@class可达性;

@interface GlobalFunction:NSObject
{
Boolean internetActive;
Boolean hostActive;

可访问性* internetReachable;
Reachability * hostReachable;
可达性* wifiReach;

}

@property(readwrite,assign)Boolean internetActive;
@property(readwrite,assign)Boolean hostActive;

- (Boolean)checkNetworkStatus;
- (BOOL)connectedToNetwork;
@end


//GlobalFunction.m

#importGlobalFunction.h
#importReachability.h
#include< netinet / in.h>
#import< SystemConfiguration / SCNetworkReachability.h>

@implementation GlobalFunction

@synthesize internetActive,hostActive;
- (id)init
{
self = [super init];
if(self){
//初始化代码在这里。
}

return self;
}



//检查Internet连接
- (布尔值)checkNetworkStatus //(NSNotification *)notice
{
//在网络状态更改后调用
internetReachable = [[Reachability reachabilityForInternetConnection] retain];
[internetReachable startNotifier];

//检查是否存在到随机主机的路径
hostReachable = [[Reachability reachabilityWithHostName:@www.apple.com] retain];
[hostReachable startNotifier];

NetworkStatus InternetStatus = [internetReachable currentReachabilityStatus];
switch(internetStatus)
{
case NotReachable:
{
// NSLog(@互联网已关闭。
// [self ShowMsg:@互联网连接似乎离线。
self.internetActive = NO;
break;

}
case ReachableViaWiFi:
{
// NSLog(@互联网是通过WIFI工作。
self.internetActive = YES;

break;

}
case ReachableViaWWAN:
{
// NSLog(@互联网正在通过WWAN工作。
self.internetActive = YES;

break;

}
默认值:
self.internetActive = YES;
break;

}

NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
switch(hostStatus)

{
case NotReachable:
{
// NSLog(@到主机服务器的网关关闭。 ;
self.hostActive = NO;

break;

}
case ReachableViaWiFi:
{
// NSLog(@主机服务器的网关通过WIFI工作。
self.hostActive = YES;

break;

}
case ReachableViaWWAN:
{
// NSLog(@主机服务器的网关通过WWAN工作。
self.hostActive = YES;

break;

}
}

[hostReachable release];
[internetReachable release];

return self.internetActive;
}

- (BOOL)connectedToNetwork {
//创建零addy
struct sockaddr_in zeroAddress;
bzero(& zeroAddress,sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
//恢复可达性标志
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL,(struct sockaddr *)& zeroAddress);
SCNetworkReachabilityFlags标志;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability,& flags);
CFRelease(defaultRouteReachability);
if(!didRetrieveFlags)
{
// NSLog(@错误,无法恢复网络可达性标志);
return 0;
}
BOOL isReachable = flags& kSCNetworkFlagsReachable;
BOOL needsConnection = flags& kSCNetworkFlagsConnectionRequired;
//下面由Ariel建议
BOOL nonWiFi = flags& kSCNetworkReachabilityFlagsTransientConnection;
NSURL * testURL = [NSURL URLWithString:@http://www.apple.com/]; // comment by friendlydeveloper:maybe use www.google.com
NSURLRequest * testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
// NSURLConnection * testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:nil]; //建议由Ariel
NSURLConnection * testConnection = [[[NSURLConnection alloc] initWithRequest:testRequest委托:nil] autorelease]; //由friendlydeveloper修改
return((isReachable&&!needConnection)|| nonWiFi)? (testConnection?YES:NO):NO;
}

- (void)dealloc {
internetReachable = nil;
hostReachable = nil;
wifiReach = nil;

[super dealloc];
}

@end




------>只需编写检查互联网的代码connection
#import< GlobalFunction.m>

- (void)viewDidLoad
{
if([globalFunc checkNetworkStatus])
{
[self ShowAlert:@Internet Connection appears];
}
else
{
[self ShowAlert:@互联网连接似乎脱机..];
}
}


I just implemented Apple's Reachability code and my App is now crashing in a completely inconsistent and random fashion: it could successfully load 20 web-pages in a row - but then crash on the 21st. attempt, or it could crash after just the 2nd. web-page load attempt

Instruments/NSZombies shows something strange: the RefCt gets to be as high as 20 (!), with the "Responsible Callers" being several different ones: [UIRuntimeConnection initWithCoder], [UINib instantiateWithOwner: options], [NSKeyedUnarchiver _decodeArrayOfObjectsForKey:], etc. Is that normal?

Or should I just focus on the last Responsible Callers? Those are [UIWindowController transitionViewDidComplete:fromView:toView:] (which brings the RefCt to 0), and [UIWebView webView:didFinishLoadForFrame:] (which takes the RefCt down to -1)?

How do I go about debugging and solving this?

Here is the Code:

#import "Reachability.h"


-(void) viewWillAppear:(BOOL)animated
{
   // check for internet connection
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];

internetReachable = [[Reachability reachabilityForInternetConnection] retain];
[internetReachable startNotifier];

// check if a pathway to a random host exists
hostReachable = [[Reachability reachabilityWithHostName: @"www.apple.com"] retain];
[hostReachable startNotifier];

// now patiently wait for the notification
}



-(void) viewDidLoad {

    url = [NSURL URLWithString: @"http://www.google.com"];
    NSURLRequest *req = [NSURLRequest requestWithURL: url];
    [webPageView loadRequest:req];
    [super viewDidLoad];
}



-(void) checkNetworkStatus:(NSNotification *)notice
{
        // called after network status changes

    NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];

    switch (internetStatus) 
    {
        case NotReachable:
        {
            //NSLog(@"The internet is down.");
            //self.internetActive = NO;   // (That's a BOOL variable)
            [self displayMessageWithTitle:@"ERROR"
                               andMessage:@"Unable To Connect to Internet"
                              andOKButton:@"OK"];
            [self dismissModalViewControllerAnimated:YES];
            break;

        }
        case ReachableViaWiFi:
        {
            //NSLog(@"The internet is working via WIFI.");
            //self.internetActive = YES;    //

            break;

        }
        case ReachableViaWWAN:
        {
            //NSLog(@"The internet is working via WWAN.");
            // self.internetActive = YES;   // (That's a BOOL variable)

            break;

        }
    }

    NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
    switch (hostStatus)
    {
        case NotReachable:
        {
            // NSLog(@"A gateway to the host server is down.");
            // self.hostActive = NO;    // (That's a BOOL variable)

            [self displayMessageWithTitle:@"ERROR"
                               andMessage:@"Host Not Reachable"
                              andOKButton:@"OK"];
            [self dismissModalViewControllerAnimated:YES];
            break;

        }

        case ReachableViaWiFi:
        {
            //NSLog(@"A gateway to the host server is working via WIFI.");
            //self.hostActive = YES;    // (That's a BOOL variable)

            break;

        }

        case ReachableViaWWAN:
        {
            //NSLog(@"A gateway to the host server is working via WWAN.");
            // self.hostActive = YES;   // (That's a BOOL variable)

            break;

        }
    }
}



- (void)webViewDidStartLoad:(UIWebView *)webView {
    [activityIndicator startAnimating];
}


- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [activityIndicator stopAnimating];
}


// Since this ViewController is presented Modally, this method removes it:
-(IBAction) dismissWebTixView:(id)sender {
    [self dismissModalViewControllerAnimated:YES];
}




-(void) viewWillDisappear:(BOOL)animated {
    NSLog(@"In webForTix's 'viewWillDisappear' method....");
    [[NSNotificationCenter defaultCenter] removeObserver:self
name:kReachabilityChangedNotification
                                              object:nil];
}


// Read somewhere that it might be better to put the removeObserver
// call here rather than viewWillDisappear...tried both - still get crashes....
- (void)dealloc
{
    //NSLog(@"In webForTix's dealloc method....");
//    [[NSNotificationCenter defaultCenter] removeObserver:self
//                                                        name:kReachabilityChangedNotification
//                                                  object:nil];
NSLog(@"In webForTix's dealloc method - removedObserver...");
[super dealloc];

}

解决方案

Try this code sure it will work.

Include Reachability.h and Reachability.m files from developer apple to your project.Import SystemConfiguration framework from SDK libraries to your project.Then add the following GlobalFunction.h and GlobalFunction.m files to your project

//GlobalFunction.h


#import <Foundation/Foundation.h>

@class Reachability;

@interface GlobalFunction  :  NSObject
{
Boolean internetActive;
Boolean hostActive;

Reachability * internetReachable;
Reachability * hostReachable;
Reachability * wifiReach;

}

@property (readwrite,assign) Boolean internetActive;
@property (readwrite,assign) Boolean hostActive;

- (Boolean) checkNetworkStatus;
- (BOOL)connectedToNetwork;
@end


//GlobalFunction.m

#import "GlobalFunction.h"
#import "Reachability.h"
#include <netinet/in.h>
#import <SystemConfiguration/SCNetworkReachability.h>

@implementation GlobalFunction

@synthesize  internetActive,hostActive;
- (id)init
{
 self = [super init];
 if (self) {
     // Initialization code here.
}

return self;
}



//  Checking Internet Connectivity
 - (Boolean) checkNetworkStatus//:(NSNotification *)notice
 {
 // called after network status changes
internetReachable = [[Reachability reachabilityForInternetConnection] retain];
[internetReachable startNotifier];

// check if a pathway to a random host exists
hostReachable = [[Reachability reachabilityWithHostName: @"www.apple.com"] retain];
[hostReachable startNotifier];

NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus)
{
    case NotReachable:
    {
        //NSLog(@"The internet is down.");
        //[self ShowMsg:@"The internet connection appears to be offline."];
        self.internetActive = NO;
        break;

    }
    case ReachableViaWiFi:
    {
        //NSLog(@"The internet is working via WIFI.");
        self.internetActive = YES;

        break;

    }
    case ReachableViaWWAN:
    {
        //NSLog(@"The internet is working via WWAN.");
        self.internetActive = YES;

        break;

    }
    default :
        self.internetActive = YES;
        break;

}

NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
switch (hostStatus)

{
    case NotReachable:
    {
        //NSLog(@"A gateway to the host server is down.");
        self.hostActive = NO;

        break;

    }
    case ReachableViaWiFi:
    {
        //NSLog(@"A gateway to the host server is working via WIFI.");
        self.hostActive = YES;

        break;

    }
    case ReachableViaWWAN:
    {
        //NSLog(@"A gateway to the host server is working via WWAN.");
        self.hostActive = YES;

        break;

    }
}

[hostReachable release];
[internetReachable release];

return self.internetActive;
}

- (BOOL)connectedToNetwork  {
// Create zero addy
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability =   SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr*)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags)
{
    //NSLog(@"Error. Could not recover network reachability flags");
    return 0;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
//below suggested by Ariel
BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"]; //comment by friendlydeveloper: maybe use www.google.com
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
//NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:nil]; //suggested by Ariel
NSURLConnection *testConnection = [[[NSURLConnection alloc] initWithRequest:testRequest delegate:nil] autorelease]; //modified by friendlydeveloper
return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
}

-(void)dealloc {
internetReachable=nil;
hostReachable=nil;
wifiReach=nil;

[super dealloc];
}

@end




------>Just write the code for checking internet connection
 #import<GlobalFunction.m>

-(void)viewDidLoad
{
 if([globalFunc checkNetworkStatus])
{
    [self ShowAlert:@"Internet Connection appears"];
}
else
{
    [self ShowAlert:@"The Internet connection appears to be offline.."];
}
}

这篇关于可达性崩溃应用程式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆