Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EXC_BAD_ACCESS with NSXMLParser and ARC

Beginner in iOS development, I'll try to realize an application which displays an RSS feed by an XML file.

In the viewDidLoad of my UITableView class, I'm using an UIActivityIndicator to wait until the data is loading.

But, at the moment that the app will be back to the main thread, I've an EXC_BAC_ACCESS code 2 at the end of the parseXMLStart function. I don't understand why...

Here the error message:

Thread 6 : 0-[NSXMLParser dealloc]
Message  : EXC_BAC_ACCESS (code=2, address=0xc)
Line     : 0xbb0840:  movl   (%eax,%ecx), %ecx

I don't know what and where is my error. How can I fix it?


Here is my code:

=> Class Type :: UITableViewController    

>> Header

@interface DataListViewController : UITableViewController {
    UIActivityIndicatorView *activityView;
    NSMutableArray *dataFromXML;
}

- (void)parseXMLStart;
- (void)parseXMLDone;

@end

>> Main

@implementation DataListViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];
    self.title = @"View 1";

    activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    activityView.center = self.view.center;

    [self performSelectorInBackground:@selector(parseXMLStart) withObject:nil];

    [activityView startAnimating];
    [activityView setHidesWhenStopped:YES];

    [self.view addSubview:activityView];
}

#pragma mark - UIActivityIndicator Methods

- (void)parseXMLStart
{
    // To Show the animation
    sleep(1);

    dataFromXML = [[NSMutableArray alloc] init];

    // COMMENT TO TEST /*

    [dataFromXML addObject:@"Element 1"];
    [dataFromXML addObject:@"Element 2"];
    [dataFromXML addObject:@"Element 3"];

    // */ COMMENT TO TEST

    // ------------------------------------------------------------------------------------------------------------------------------------

    // UNCOMMENT TO TEST
    /*

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"words" ofType:@"xml"];
    NSURL *url = [[NSURL alloc] initWithString:[[NSString stringWithFormat:@"file://%@",filePath] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];

     XML2ObjectParser *parserWords = [[XML2ObjectParser alloc] parseXMLAtURL:url toObject:@"Word" parseError:nil];

    NSLog(@">> parserWords Items Count :: %i", parserWords.items.count);

    for (int i = 0; i < [parserWords.items count]-1; i++) {
        Word *aWord = [[Word alloc] init];
        aWord = (Word *)[[parserWords items] objectAtIndex:i];
        [dataFromXML addObject:aWord];
    }

    NSLog(@">> dataFromXML Count :: %i", dataFromXML.count);

    */
    // UNCOMMENT TO TEST

    // --------------------------------------------------------------------------------------------------------------------------------------------

    // EXC_BAD_ACCESS (code=2, address=0xc)
    // Thread 6 : 0-[NSXMLParser dealloc]
    // 0xbad840:  movl   (%eax,%ecx), %ecx

    // --------------------------------------------------------------------------------------------------------------------------------------------

    [self performSelectorOnMainThread:@selector(parseXMLDone) withObject:nil waitUntilDone:YES];
}

- (void)parseXMLDone
{
    [activityView stopAnimating];
    [self.tableView reloadData];
}

# pragma mark - Table View Method

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [dataFromXML count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"CellID";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
    }

    cell.textLabel.text = [dataFromXML objectAtIndex:[indexPath row]];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    DataListDetailViewController *_dataListDetailViewController = [[DataListDetailViewController alloc] init];

    _dataListDetailViewController.title = [dataFromXML objectAtIndex:[indexPath row]];

    [self.navigationController pushViewController:_dataListDetailViewController animated:YES];
}

@end
like image 213
iMiko Avatar asked Mar 10 '26 23:03

iMiko


2 Answers

It looks to me like your selector is typed incorrectly. you have @selector(parsingXMLDone) and it should be @selector(parseXMLDone)

like image 54
El Guapo Avatar answered Mar 13 '26 14:03

El Guapo


I've find the error.

It wasn't my mistake but the ARC.

I'm explain, when parsing XML it's finished, the background thread is killed and after ARC wants to dealloc the NSXMLParser.

That's why, it causes an EXC_BAD_ACCESS, Because ARC want to dealloc an already deallocated object (AKA NSXMLParser).

The solution was to compile my class without ARC, using the flag "fno-objc-arc" in the Build Phases of the Target.

See : NSXMLParser gives EXC_BAD_ACCESS only with ARC enabled

Thanks for the help.

like image 32
iMiko Avatar answered Mar 13 '26 16:03

iMiko