Blade
Blade

Reputation: 1437

tableView crashes when adding the first item (and also when deleting last item)

After cleaning up my code and making it ready for deployment I encountered a weird problem. When I try to add a contact to my tableview it always crashes when the empty is array. After that its not problem to add as many as you want. And also when I delete a contact and the array is empty, it also crashes with the same error message:

Terminating app due to uncaught exception 'NSRangeException', reason: ' -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'

Here is what I do: I add a contact via php to my database, read it out with xml and give it back to the app so the user can instantly see what happened (adding a contact that is). There is a lot of code involved so I stick to the basics for now. When the view loads the array gets allocated. User can add a contact. While adding the contact a php file is called that creates the xml file where the contacts are saved.

Here is where I get the object back and paste it into my array and display it

self.filteredListContent = [NSMutableArray arrayWithCapacity:[self.tabelle count]];

self.tableView.scrollEnabled = YES;

numbers = [[NSMutableArray alloc] init];

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; 
NSString *fileName = [prefs stringForKey:@"number"];
NSString *cc = [prefs stringForKey:@"Code"];
NSString *urlString = [NSString stringWithFormat: @"http://myserver/%@%@.xml", cc, fileName];
NSURL *url = [NSURL URLWithString: urlString];

DataFileToObjectParser *myParser = [[DataFileToObjectParser alloc] parseXMLAtUrl:url toObject:@"contacts" parseError:nil];

for(int i = 0; i < [[myParser items] count]; i++) {
    contacts *new = [[Telefonbuch alloc] init];
    new = (contacts *) [[myParser items] objectAtIndex:i];
    [numbers addObject:new];
    [self.tableView reloadData];

And here is how it gets displayed, nothing special:

NSString *TableText = [[NSString alloc] initWithFormat:@"%@", [[numbers objectAtIndex:indexPath.row] fname]]; 
NSString *TableText2 = [[NSString alloc] initWithFormat:@"%@", [[numbers objectAtIndex:indexPath.row] lname]];    
NSString *cellValue = [NSString stringWithFormat:@"%@ %@", TableText, TableText2];
cell.textLabel.text = cellValue;

Upvotes: 0

Views: 112

Answers (1)

Lorenzo B
Lorenzo B

Reputation: 33428

Your loop sounds strange.

for(int i = 0; i < [[myParser items] count]; i++) {
    contacts *new = [[Telefonbuch alloc] init];
    new = (contacts *) [[myParser items] objectAtIndex:i];
    [numbers addObject:new];
    [self.tableView reloadData];

First avoid to use new keyword (as user1118321 already suggested).

Then, what is contacts? Is contacts a superclass of type Telefonbuch?

What do these two lines mean?

contacts *new = [[Telefonbuch alloc] init];
new = (contacts *) [[myParser items] objectAtIndex:i];

You alloc-init an instance of Telefonbuch class to a new (avoid this) variable but then you assign that variable to another object. Why?

The right code could be like the following.

for(int i = 0; i < [[myParser items] count]; i++) {
   Telefonbuch* newContact = (Telefonbuch*) [[myParser items] objectAtIndex:i]; // or contacts* newContact = (contacts*) [[myParser items] objectAtIndex:i];
   // maybe it could be better to rename contacts with a capital letter
   [numbers addObject:newContact];
}

[self.tableView reloadData];

Some notes

If you want to add or delete item to a table view, you need to do it in 2 stages:

1) Deal with your model

[yourModel removeObjectAtIndex:row];

2) Deal with your table’s animation

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

If you need to download content, maybe you could consider to do it asynchrously without blocking the main thread. In particular, this is could be the synchronous call that could be a blocking one (since I don't have any details I'm only supposing it).

DataFileToObjectParser *myParser = [[DataFileToObjectParser alloc] parseXMLAtUrl:url toObject:@"contacts" parseError:nil];

If you don't use ARC, pay attention to memory management.

Hope it helps.

Upvotes: 1

Related Questions