简体   繁体   中英

iOS tableview refresh issue

My application uses a table that is populated by a dynamic xml feed. I am also using the pull to refresh code written by Grant Paul to reload the table with new content, if there is some. Thirdly, I am using Apple's Reachability to determine internet connectivity when reloading the table. My problem is this; If I open the application WITH internet connection, then while the app is running, shut of my internet connection, I then pull to refresh the application and it crashes. Something is happening when the app is switching between Reachable and NotReachable. Below is my code. The app fails with a Thread 6: signal SIGABRT on this line: TFHppleElement *element = [elements objectAtIndex:0];

Here is the error code:

2012-10-02 14:00:03.715 FireCom[2229:1517] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack:
(0x2d63012 0x21a0e7e 0x2d050b4 0x603f 0xd810d5 0xd81034 0x96213557 0x961fdcee)
libc++abi.dylib: terminate called throwing an exception
(lldb)

Here is the Reachability code:

- (void)loadCallList
{
Reachability* reach = [Reachability reachabilityWithHostname:@"www.apple.com"];
NetworkStatus netStatus = [reach currentReachabilityStatus];

switch (netStatus)
{
    case NotReachable:
    {
        NSLog(@"Access Not Available");

        [pull finishedLoading];
        [self displayInternetMessage];

        break;
    }

    case ReachableViaWWAN:
    {
        NSLog(@"Reachable WWAN");

        // Parse HTML for random ID and create XML link

        NSURL *theURL = [NSURL URLWithString:@"http://www.wccca.com/PITS/"];
        NSData *data = [[NSData alloc] initWithContentsOfURL:theURL];
        xpathParser = [[TFHpple alloc] initWithHTMLData:data];
        NSArray *elements = [xpathParser searchWithXPathQuery:@"//input[@id='hidXMLID']//@value"];
        TFHppleElement *element = [elements objectAtIndex:0];
        TFHppleElement *child = [element.children objectAtIndex:0];
        NSString *idValue = [child content];

        NSString *idwithxml = [idValue stringByAppendingFormat:@".xml"];
        NSString *url = @"http://www.wccca.com/PITS/xml/fire_data_";
        NSString *finalurl = [url stringByAppendingString:idwithxml];

        xmlParser = [[XMLParser alloc] loadXMLByURL:finalurl];

        if (xmlParser.calls.count == 0)
        {
            self.headerHeight = 0.0;
            UIAlertView *noCalls = [[UIAlertView alloc] initWithTitle:@"No Current Calls"
                                                              message:@"There are no current 9-1-1 calls in Clackamas or Washington County."
                                                             delegate:self
                                                    cancelButtonTitle:@"OK"
                                                    otherButtonTitles:nil];

            [noCalls show];
            [noCalls release];
        }
        else
        {
            self.headerHeight = 45.0;
        }

        [callsTableView reloadData];
        [pull finishedLoading];

        break;
    }
    case ReachableViaWiFi:
    {
        NSLog(@"Reachable WiFi");

        // Parse HTML for random ID and create XML link

        NSURL *theURL = [NSURL URLWithString:@"http://www.wccca.com/PITS/"];
        NSData *data = [[NSData alloc] initWithContentsOfURL:theURL];
        xpathParser = [[TFHpple alloc] initWithHTMLData:data];
        NSArray *elements = [xpathParser searchWithXPathQuery:@"//input[@id='hidXMLID']//@value"];
        TFHppleElement *element = [elements objectAtIndex:0];
        TFHppleElement *child = [element.children objectAtIndex:0];
        NSString *idValue = [child content];

        NSString *idwithxml = [idValue stringByAppendingFormat:@".xml"];
        NSString *url = @"http://www.wccca.com/PITS/xml/fire_data_";
        NSString *finalurl = [url stringByAppendingString:idwithxml];

        xmlParser = [[XMLParser alloc] loadXMLByURL:finalurl];

        if (xmlParser.calls.count == 0)
        {
            self.headerHeight = 0.0;

            UIAlertView *noCalls = [[UIAlertView alloc] initWithTitle:@"No Current Calls"
                                                              message:@"There are no current 9-1-1 calls in Clackamas or Washington County."
                                                             delegate:self
                                                    cancelButtonTitle:@"OK"
                                                    otherButtonTitles:nil];

            [noCalls show];
            [noCalls release];
        }
        else
        {
            self.headerHeight = 45.0;
        }

        [callsTableView reloadData];
        [pull finishedLoading];

        break;
    }
}
}

I think I see your problem.

NSArray *elements = [xpathParser searchWithXPathQuery:@"//input[@id='hidXMLID']//@value"];
TFHppleElement *element = [elements objectAtIndex:0];
TFHppleElement *child = [element.children objectAtIndex:0];

You can't assume elements has a count of at least on 1.


Update

Maybe try something like

NSArray *elements = [xpathParser searchWithXPathQuery:@"//input[@id='hidXMLID']//@value"];
if (elements.count < 1) {
    // Any needed cleanup
    break;
}

TFHppleElement *element = [elements objectAtIndex:0];
TFHppleElement *child = [element.children objectAtIndex:0];

as a fast way out.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM