Michael O'Rourke
Michael O'Rourke

Reputation: 85

Why do I have a memory leak in UITableView while interacting and scrolling?

my tableview is working fine and loading all the data without issues. I run into problems when I use didSelectRowAtIndexPath and add/remove the checkbox on the cell. I'll check a cell in the first 10, scroll down and see a checkbox on a cell I didn't tap.

What is causing this issue? Below is my tableview code.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = @"reuseCellForFilter";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
Category *category = [self.categories objectAtIndex:indexPath.row];
cell.textLabel.text = category.title;

return cell;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.categories.count;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath   *)indexPath
{


NSLog(@"%@", indexPath);
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
Category *category = [self.categories objectAtIndex:indexPath.row];
if(cell.accessoryType == UITableViewCellAccessoryNone) {
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    [self.titles addObject:category];
}
else {
    cell.accessoryType = UITableViewCellAccessoryNone;
    for (Category *categoryID in [self.titles reverseObjectEnumerator]) {
        if (categoryID.categoryID == category.categoryID) {
            [self.titles removeObject:categoryID];
        }
    }
}
}

Upvotes: 0

Views: 605

Answers (1)

Mikhail Grebionkin
Mikhail Grebionkin

Reputation: 3846

You need to save checked/unchecked state in your didSelectRowAtIndexPath method and then restore it in cellForRowAtIndexPath method.

For example:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = @"reuseCellForFilter";
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    cell.selectionStyle = [self.selected containsObject:category.categoryID] ? UITableViewCellSelectionStyleCheckmark : UITableViewCellSelectionStyleNone;
    Category *category = [self.categories objectAtIndex:indexPath.row];
    cell.textLabel.text = category.title;
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath   *)indexPath
{
    Category *category = [self.categories objectAtIndex:indexPath.row];
    if ([self.selected containsObject:category.categoryID]) {
        [self.selected removeObject:category.categoryID];
        self.tableView reloadRowsAtIndexPaths:@[indexPath] withAnimation: UITableViewRowAnimationNone];
    }
}

You also have a problem in didSelectRowAtIndexPath method. Marking category as checked you add this category to an array. To uncheck category you remove categoryID from array.

[self.titles addObject:category];
...
[self.titles removeObject:categoryID];

Upvotes: 2

Related Questions