EXC_BAD_ACCESS in heightForRowAtIndexPath iOS

后端 未结 5 1376
眼角桃花
眼角桃花 2020-11-28 14:27

I\'m working on an application where I have a custom subclass of UITableViewCell. I want to make the cell\'s height dynamic based on the text inside it. I try do do that in

5条回答
  •  被撕碎了的回忆
    2020-11-28 14:43

    I have tried to reproduce the problem. It turns out that calling cellForRowAtIndexPath: inside heightForRowAtIndexPath causes heightForRowAtIndexPath to be called recursively. Here is an extract of the stack backtrace after the 3 recursion steps:

    frame #0: 0x000042d0 DocInteraction`-[DITableViewController tableView:heightForRowAtIndexPath:] + 48 at DITableViewController.m:262
    frame #1: 0x0054f688 UIKit`-[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 3437
    frame #2: 0x0055040f UIKit`-[UITableViewRowData(UITableViewRowDataPrivate) _ensureSectionOffsetIsValidForSection:] + 144
    frame #3: 0x00551889 UIKit`-[UITableViewRowData numberOfRows] + 137
    frame #4: 0x00553dac UIKit`-[UITableViewRowData globalRowsInRect:] + 42
    frame #5: 0x003f82eb UIKit`-[UITableView(_UITableViewPrivate) _visibleGlobalRowsInRect:] + 177
    frame #6: 0x004001e6 UIKit`-[UITableView cellForRowAtIndexPath:] + 113
    frame #7: 0x000042f2 DocInteraction`-[DITableViewController tableView:heightForRowAtIndexPath:] + 82 at DITableViewController.m:262
    frame #8: 0x0054f688 UIKit`-[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 3437
    frame #9: 0x0055040f UIKit`-[UITableViewRowData(UITableViewRowDataPrivate) _ensureSectionOffsetIsValidForSection:] + 144
    frame #10: 0x00551889 UIKit`-[UITableViewRowData numberOfRows] + 137
    frame #11: 0x00553dac UIKit`-[UITableViewRowData globalRowsInRect:] + 42
    frame #12: 0x003f82eb UIKit`-[UITableView(_UITableViewPrivate) _visibleGlobalRowsInRect:] + 177
    frame #13: 0x004001e6 UIKit`-[UITableView cellForRowAtIndexPath:] + 113
    frame #14: 0x000042f2 DocInteraction`-[DITableViewController tableView:heightForRowAtIndexPath:] + 82 at DITableViewController.m:262
    frame #15: 0x0054f688 UIKit`-[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 3437
    frame #16: 0x0055040f UIKit`-[UITableViewRowData(UITableViewRowDataPrivate) _ensureSectionOffsetIsValidForSection:] + 144
    frame #17: 0x00551889 UIKit`-[UITableViewRowData numberOfRows] + 137
    frame #18: 0x003ff66d UIKit`-[UITableView noteNumberOfRowsChanged] + 119
    frame #19: 0x003ff167 UIKit`-[UITableView reloadData] + 764
    

    Finally the program crashes. On my Simulator this happens when the back trace is about 57000 levels deep.


    Old answer (not wrong, but does not explain the EXC_BAD_ACCESS):

    The problem is that

    [tableView cellForRowAtIndexPath:indexPath]
    

    returns nil for rows that are currently not visible. A table view allocates only so many cells that are required to display the currently visible rows. The cells are reused when you scroll the table view.

    But heightForRowAtIndexPath is called for all cells of the table view before any row is displayed.

    As a consequence, you should not get the text from the table view cells to compute the height in heightForRowAtIndexPath. You should get the text from your data source instead.

提交回复
热议问题