简短的问题是:我们可以强制tableView:cellForRowAtIndexPath
为“非显示的单元格”(例如,单元格8到25)调用,以便我们预取图像来自服务器,如果表只有20行或25行,则永远不会重复使用单元格?
详细信息:我认为tableView:cellForRowAtIndexPath
的机制主要是为了保留内存,尤其是在iPhone或iPod Touch上,所以如果一个表有1000行,就不会有1000 UITableViewCell
个对象(UITableViewCell
是UIView
的子类),它将使用大量内存,但只有10个对象左右,这些对象可以“重用”,所以内存使用可以保持小规模。
但是如果每一行都有在服务器上获取的图像怎么办?我们不是使用单独的线程构建单独的图像缓存,而是让tableView:cellForRowAtIndexPath
获取前7个图像并显示表格,稍后,强制渲染单元格8到25,并且永远不要调用{{1} (所以我们有25个这样的dequeueReusableCellWithIdentifier
个对象而不重用它们。如何做到这一点,它实际上是一个实用而简单的解决方案吗?
答案 0 :(得分:6)
缓存图像几乎不属于视图层;也没有从服务器中检索这些图像。
您应该采用您在帖子中描述的方法 - 从表中单独缓存图像,然后从该图像缓存中检索这些图像。
您可以构建一个ImageProvider
类,根据其键为您提供图像,并使用该提供程序构建表格单元格。反过来,ImageProvider
决定是从服务器加载图像还是从缓存加载图像,从表视图中隐藏细节。
这种方法为您提供了很大的灵活性:如果您决定通过在设备上本地缓存图像来节省网络流量,那么使用单独缓存的方法可以在不干扰视图层的情况下实现这一点。它还允许您通过将缓存的图像刷新到临时文件来节省内存,例如,在收到低内存警告时。
答案 1 :(得分:0)
您无法强制UITableView
拨打tableView:cellForRowAtIndexPath
。
我能想到的解决方法是提前创建UITableViewCell
个实例,将它们存储在NSArray
中并让tableView:cellForRowAtIndexPath
返回您已经创建的实例,索引前面的数组创建了行。
答案 2 :(得分:0)
虽然这是一个糟糕的想法,但可以通过创建与表一样大的UIScrollView,然后添加一个禁用滚动的UITableView来实现。
CGSize tableSize = CGSizeMake(320, 1000);
UIScrollView* aScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, tableSize.width, tableSize.height)];
UITableView* aTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, tableSize.width, tableSize.height)];
aTableView.scrollEnabled = NO;
[aScrollView addSubview:aTableView];
[aTableView release];
[self.view addSubview:aScrollView];
[aScrollView release];
答案 3 :(得分:0)
最好预取所需的所有图像,而不是加载所有单元格。我建议用于此目的SDWebImage。它还包含一个image prefetcher,您可以在显示UITableView内容之前加载所有图像。