2011-12-02 34 views
0

我刚刚实现了Apple的Reachability代码,现在我的应用以完全不一致和随机的方式崩溃:它可以成功加载20个网页 - 但之后会在第21次崩溃。尝试,或者可能会在第二次之后崩溃。网页加载尝试可达性崩溃应用

仪器/ NSZombies显示了一些奇怪的事情:RefCt变得高达20(!),“Responsible Callers”有几个不同的:[UIRuntimeConnection initWithCoder],[UINib instantiateWithOwner:options ],[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]等 这是正常的吗?

或者我应该只关注最后的负责任呼叫者? 这些是[UIWindowController transitionViewDidComplete:fromView:toView:](它使RefCt为0)和 [UIWebView webView:didFinishLoadForFrame:](它将RefCt降至-1)?

我该如何去调试和解决这个问题?

这里是代码:

#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]; 

}

+3

你需要告诉使用微尘细节。 'EXC_BAD_ACCESS'告诉我们一些被调用的对象可能已被释放。首先[启用NSZombies](http://stackoverflow.com/questions/5386160/how-to-enable-nszombie-in-xcode)。然后看看为什么这个对象被释放。 – rckoenes

+0

好的我打开僵尸,它在崩溃时显示-1的RefCt。在“类别”列中,它告诉我导致崩溃的ViewController的名称 - 其中引入Reachability的VC以及调用Reachability方法的名称。奇怪的是,RefCt在减小到0和-1之前变得很高。为什么这样做? ViewController只调用一次,然后关闭并运行它的事情 - 这是在加载网页时检查连接性。它是否反复调用自己一遍又一遍? – sirab333

+0

你需要显示你的代码。 – Eiko

回答

-1

试试这个代码肯定会工作。

包括从开发苹果的project.Import SystemConfiguration框架从SDK库Reachability.h和Reachability.m文件到您的project.Then以下GlobalFunction.h和GlobalFunction.m文件添加到您的项目

//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.."]; 
} 
}