0

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

}

sirab333
  • 3,662
  • 8
  • 41
  • 54
  • 3
    You need to tells use mote detail. the `EXC_BAD_ACCESS` just tells us some object was called which probably been deallocated. First [enable NSZombies](http://stackoverflow.com/questions/5386160/how-to-enable-nszombie-in-xcode). Then have a look why that object is deallocated. – rckoenes Dec 02 '11 at 13:02
  • ok I turned Zombies on and it shows a RefCt of -1 upon crashing. In the "Categories" column it tells me the name of the ViewController causing the crash - its the VC into which Reachability is imported and where the Reachability methods are called. What's weird is that the RefCt gets as high 17 before getting decremented all the way back to 0, and then -1. Why is it doing that? The ViewController is only called once, and then its off and running doing its thing - which is checking for connectivity while loading a web-page. Is it recursivley calling itself over and over? – sirab333 Dec 02 '11 at 14:45

1 Answers1

-1

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.."];
}
}
SURESH SANKE
  • 1,653
  • 17
  • 34