我正在开发一个应用程序,我有一个UITableViewCell的自定义子类。我想根据里面的文字使单元格的高度动态变化。我尝试在我的heightForRowAtIndexPath方法中这样做。但我有一些问题,以下代码导致和EXC_BAD_ACCESS(代码= 2地址= 0xb7ffffcc)错误。
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 my heightForRowAtIndexPath method. But I'm having some issues, the following code causes and EXC_BAD_ACCESS(code=2 address=0xb7ffffcc) error.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { PostCell *cell = (PostCell *)[tableView cellForRowAtIndexPath:indexPath]; CGSize postTextSize; if (![cell.postText.text isEqualToString:@""]) { postTextSize = [cell.postText.text sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(cell.postText.frame.size.width, 200)]; } else { postTextSize = CGSizeMake(cell.postText.frame.size.width, 40); } return postTextSize.height + cell.userName.frame.size.height + 10; }如果我改为:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 100; }它有效。
这一行似乎崩溃了: PostCell * cell =(PostCell *)[tableView cellForRowAtIndexPath:indexPath]; ,我不知道为什么。我试图建立干净并重置模拟器,但都没有工作。任何想法为什么会这样?
It seems to be crashing on this line: PostCell *cell = (PostCell *)[tableView cellForRowAtIndexPath:indexPath];, and I don't know why. I have tried to build clean and reset the simulator, but neither worked. Any ideas why this is happening?
推荐答案我试图重现这个问题。事实证明,在 heightForRowAtIndexPath 内调用 cellForRowAtIndexPath:会导致 heightForRowAtIndexPath 被递归地调用。以下是3个递归步骤之后的堆栈回溯的摘录:
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最后程序崩溃了。在我的模拟器上,这种情况发生在后跟踪深度约为57000级时。
Finally the program crashes. On my Simulator this happens when the back trace is about 57000 levels deep.
旧答案 (没错,但不解释 EXC_BAD_ACCESS):
Old answer (not wrong, but does not explain the EXC_BAD_ACCESS):
问题是
[tableView cellForRowAtIndexPath:indexPath]返回 nil 表示当前不可见的行。表视图仅分配显示当前可见行所需的许多单元格。滚动表格视图时会重复使用这些单元格。
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.
但 all heightForRowAtIndexPath em>在显示任何行之前的表视图的单元格。
But heightForRowAtIndexPath is called for all cells of the table view before any row is displayed.
因此,您不应该从表格视图单元格中获取文本以计算 heightForRowAtIndexPath 。您应该从数据源获取文本。
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.
更多推荐
iOS中的EXC
发布评论