我有一个与我的uitableview绑定的SQLite数据库。大约有2000行,所以我首先检索25行。一旦我滚动到列表的末尾,我希望它自动检索25行。
这是我现在使用的方法。忽略如果我加载所有2000行会发生什么,我稍后会担心。在tableView:numberOfRowsInSection:
中,我返回的比当前加载的行多一个。然后在tableView:cellForRowAtIndexPath:
中,如果加载最后一行,我会加载更多行。
通常我可以下几页,但我最终得到一个例外:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (10) beyond bounds (10)'
。指数总是8-10。我不知道它是什么数组,但我的rows
和indices
数组都有超过10个项目。
tableView:cellForRowAtIndexPath:
if(indexPath.row >= [rows count]) {
[cell.textLabel setText:@"Loading..."];
if(!updating && indexPath.row == [rows count]) {
updating = YES;
[[self tableView] beginUpdates];
NSMutableArray *indices = [NSMutableArray array];
// stmt = ...
while(sqlite3_step(stmt) == SQLITE_ROW) {
[rows addObject:@"..."];
[indices addObject:[NSIndexPath indexPathForRow:[rows count]-1 inSection:0]];
}
[[self tableView] insertRowsAtIndexPaths:indices withRowAnimation:UITableViewRowAnimationNone];
[[self tableView] endUpdates];
updating = NO;
}
return cell;
}
堆栈追踪:
#0 0x01ce4004 in ___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION___ ()
#1 0x9779df49 in objc_exception_throw ()
#2 0x01cc5c3b in +[NSException raise:format:arguments:] ()
#3 0x01cc5b9a in +[NSException raise:format:] ()
#4 0x00072cc9 in _NSArrayRaiseBoundException ()
#5 0x00010227 in -[NSCFArray objectAtIndex:] ()
#6 0x0047fe5b in -[_UITableViewUpdateSupport(Private) _setupAnimationsForExistingVisibleCells] ()
#7 0x0047f9e0 in -[_UITableViewUpdateSupport initWithTableView:updateItems:oldRowData:newRowData:oldRowRange:newRowRange:context:] ()
#8 0x002eca2b in -[UITableView(_UITableViewPrivate) _updateWithItems:withOldRowData:oldRowRange:newRowRange:context:] ()
#9 0x002ec757 in -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] ()
#10 0x002def56 in -[UITableView endUpdates] ()
答案 0 :(得分:4)
我有点不清楚为什么要插入行。在我看来,你使这个变得比它需要的复杂得多。 UITableView
只会询问您屏幕上(或很快会)的表格单元格的值。更重要的是,通过不断向表格视图添加行,滚动条不会反映用户在数据集中的实际位置。
返回tableView:numberOfRowsInSection:
中的总行数(您可以使用SQLite COUNT
聚合函数执行此操作而不实际获取所有数据)并缓存其他内容同样有意义当您遇到“缓存未命中”时,根据需要使用数据(使用类似于上面的内容)。
如果我不得不猜测为什么这段代码会导致你出现问题,那么当你的表视图等待你返回一个单元格时,就会修改表格视图的内容。
我会建议看起来更像这样的东西:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath row] >= [cache count]) {
// Load additional items into the cache
}
// Do the regular cell setup stuff here; you can assume the data you need is available
return cell;
}
答案 1 :(得分:0)
您在返回单元格时更新tableview的注释促使我实现- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
以在需要时加载更多行,这更稳定,尽管我必须在单独的线程中这样做以获得任何类型的性能
您的解决方案也有效,并且肯定比我当前的方法更简单。我必须决定是否希望滚动条显示实际位置或更有形的位置。至少对我而言,感觉应用程序正在加载许多对象,因此当滚动条太小时,它会变慢。