Skip to content

Commit 5e06d3d

Browse files
Tyler FoxTyler Fox
authored andcommitted
Fix memory leak by using a dictionary of offscreen cells for height calculations
This method replaces the previous usage of dequeueReusableCellWithIdentifier: from within tableView:heightForRowAtIndexPath:, which causes cells to be leaked because they are never returned from tableView:cellForRowAtIndexPath:
1 parent bf36877 commit 5e06d3d

1 file changed

Lines changed: 19 additions & 1 deletion

File tree

TableViewCellWithAutoLayout/TableViewController/RJTableViewController.m

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ @interface RJTableViewController ()
3434

3535
@property (strong, nonatomic) RJModel *model;
3636

37+
// A dictionary of offscreen cells that are used within the tableView:heightForRowAtIndexPath: method to
38+
// handle the height calculations. These are never drawn onscreen. The dictionary is in the format:
39+
// { NSString *reuseIdentifier : UITableViewCell *offscreenCell, ... }
40+
@property (strong, nonatomic) NSMutableDictionary *offscreenCells;
41+
3742
// This property is used to work around the constraint exception that is thrown if the
3843
// estimated row height for an inserted row is greater than the actual height for that row.
3944
// See: https://github.com/caoimghgin/TableViewCellWithAutoLayout/issues/6
@@ -49,6 +54,7 @@ - (id)initWithStyle:(UITableViewStyle)style
4954
if (self) {
5055
self.model = [[RJModel alloc] init];
5156
[self.model populateDataSource];
57+
self.offscreenCells = [NSMutableDictionary dictionary];
5258
}
5359
return self;
5460
}
@@ -148,7 +154,19 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
148154

149155
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
150156
{
151-
RJTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
157+
// This project has only one cell identifier, but if you are have more than one, this is the time
158+
// to figure out which reuse identifier should be used for the cell at this index path.
159+
NSString *reuseIdentifier = CellIdentifier;
160+
161+
// Use the dictionary of offscreen cells to get a cell for the reuse identifier, creating a cell and storing
162+
// it in the dictionary if one hasn't already been added for the reuse identifier.
163+
// WARNING: Don't call the table view's dequeueReusableCellWithIdentifier: method here because this will result
164+
// in a memory leak as the cell is created but never returned from the tableView:cellForRowAtIndexPath: method!
165+
RJTableViewCell *cell = [self.offscreenCells objectForKey:reuseIdentifier];
166+
if (!cell) {
167+
cell = [[RJTableViewCell alloc] init];
168+
[self.offscreenCells setObject:cell forKey:reuseIdentifier];
169+
}
152170

153171
// Configure the cell for this indexPath
154172
[cell updateFonts];

0 commit comments

Comments
 (0)