views:

574

answers:

1

I have a refresh button in the toolbar that regenerates an NSArray and attempts to reload the contents of the table.

However, whether I have:

if (boolCondition) {
   [self refreshTableDataSet];
   [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:kTableSectionOfInterest] withRowAnimation:UITableViewRowAnimationFade];
}

or:

if (boolCondition) {
   [self refreshTableDataSet];
   [self.tableView reloadData];
}

About every other attempt to refresh the table fails. Sometimes it works, sometimes not.

I have some NSLog statements in -tableView:cellForRowAtIndexPath: to let me know when this method is being fired. When the refresh fails, I do not see the output of these NSLog statements.

Is there something I'm missing about reloading a table view, when I have new data?

EDIT

In my -refreshTableDataSet method:

- (void) refreshTableDataSet {
   NSSortDescriptor *_objectTypeSorter = [[[NSSortDescriptor alloc] initWithKey:@"object.type" ascending:YES] autorelease];
   NSSet *_objectSet = [managedObjectContext fetchObjectsForEntityName:@"Object" withPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"group.name like '%@'", [group name]]]];
   self.objects = [[[_objectSet allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObjects: _objectTypeSorter, nil]] retain];
}

In my table view -tableView:cellForRowAtIndexPath: method:

...
Object *_object = [self.objects objectAtIndex:indexPath.row];
if (cell == nil) {
   cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = _object.name;
cell.detailTextLabel.text = _object.type;
cell.imageView.image = [UIImage imageNamed:@"GroupType.png"];
cell.accessoryView = [self imageViewForObjectDetailType:_object.type];
...

I have a method for the accessoryView called -imageViewForObjectDetailType, which just returns a UIImageView:

return [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"GenericObjectDetailType.png"]] autorelease];

Are there retain and/or release messages that I am missing?

A: 

I'm sure you've checked this, but I see random behavior like this if I have an NSArray that wasn't retained and passed on to a tableview.

Looking at your added code, I don't see anything wrong at first glance - here are some tips:

1.In:

self.objects = [[[_objectSet allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObjects: _objectTypeSorter, nil]] retain];

If objects is a @property with retain attribute, then you don't need to retain it here again. Not why it would fail though.

2.In your cellForRowAtIndexPath, you do have something like:

UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

just before the if (cell == nil), right?

3.You might want to NSLog the value of object when you get it from the array in

Object *_object = [self.objects objectAtIndex:indexPath.row];

4.Break this up onto multiple lines and look at all the return values with NSLog to make sure they all succeed every time you refresh.

self.objects = [[[_objectSet allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObjects: _objectTypeSorter, nil]] retain];

5.Double check this to make sure your fetch is getting you what you expect:

NSSet *_objectSet = [managedObjectContext fetchObjectsForEntityName:@"Object" withPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"group.name like '%@'", [group name]]]];

You can NSLog the [_objectSet count] to watch to see whether an unsuccessful refresh gives you a bad count.

Hope this helps.

mahboudz
I have added code which shows how I am setting up my `NSArray`. Does it look like I'm missing something? Thanks!
Alex Reynolds
I had my `if (cell==nil)` test in the wrong place. I have a switch-case tree and had to move that conditional to each case block. Thanks for your thorough ideas.
Alex Reynolds
Good sleuthing!
mahboudz