2011-12-02 70 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.."]; 
} 
}