tableView:cellForRowAtIndexPath:不仅为可见单元格调用? [英] tableView: cellForRowAtIndexPath: get called not only for visible cells?

查看:33
本文介绍了tableView:cellForRowAtIndexPath:不仅为可见单元格调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有部分的 tableView,可以打开和关闭.所以,当我点击一个部分打开它时,它被单元格填满,并且 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) 被调用的次数完全相同我在 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 中提供的次数.

I have a tableView with sections, which could be opened and closed. So, when I tap on a section to open it, it is getting filled up with cells and -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) get called exactly as much times as I provided in -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section.

这样对吗?不应该只是可见单元格的数量吗?

Is that correct? Shouldn't it be just number of visible cells?

因为在我的情况下,我的情况很糟糕:我有很多自定义单元格(50~100 个单元格)并调用 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) 对于每个单元格会减慢一个部分的打开速度,导致每次从 nib 读取时都会使用图像填充单元格内容.我已经检查了 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) 中单元格的可见性,如下所示:

Because in my case I have bad situation: I have a lot of custom cells (50~100 cells) and calling -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) for each cell slows down the opening of a section, cause each time reading from nib is performed and cell content is being populated with image. I've check visibility of cell inside -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) like this:

if ([[self.tableView indexPathsForVisibleRows] containsObject:indexPath])
    NSLog(@"visible %@", indexPath);

并且它显示在 45 个单元格中,只有 6 或 7 个是可见的.其他人在可见区域之外.但是仍然可以创建单元格.代码如下:

and it shows that from out of 45 cells, only 6 or 7 are visible. Others are out of visible area. But creating cells still performed. Here is the code:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath    {
static NSString *CellIdentifier = @"IVCell";
IVCamera *camera = [server.cameras objectAtIndex:indexPath.row];

IVServerListViewCell *cell = (IVServerListViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"IVServerListCell" owner:self options:nil];
    cell = (IVServerListViewCell*)_tableViewCell;
    self.tableViewCell = nil;

}

[cell textLabel].text = camera.cameraName;
cell.preview = camera.preview;
cell.userData = camera; 
cell.isEnabled = (server.isInactive)?NO:camera.isOnline;

return cell;
}

它仍然正确吗?还是我遗漏了什么?

Is it still correct? Or am I missing something?

推荐答案

好吧,我以某种方式处理了我的问题.这是我如何找到解决方案的想法和想法.也许它可能对某人有帮助.

Well, I somehow dealt with my problem. Here are my ideas and thoughts how I came to the solution. Maybe it could be helpful to somebody.

我已经在打开部分事件期间使用 Instruments 指示内存分配和调用堆栈.它告诉我,大部分时间都花在从 nib 文件加载单元格上.

I've instructed memory allocations and call stack using Instruments during opening section events. It showed me, that the majority of time is spent on loading cell from nib file.

首先,我所做的是减小 nib 文件的大小,即最小化自定义 tableview 单元格中使用的视图数量(现在只有 2 个视图和 2 个标签,而不是 6 个视图,之前有 2 个图像和 2 个标签).它给了我一些单元格加载的改进.Apple 文档建议使用尽可能少的视图并且不要使用透明度.所以请注意这些建议.

Firstly, that I've done was reducing the size of nib file, i.e. minimizing the number of views used in custom tableview cell (now its only 2 views and 2 labels, instead of 6 views, 2 images and 2 labels before). It gave me some improve in cells loading. Apple documentation suggests to use as few as possible views and do not use transparency. So be attentive to these suggestions.

其次,正如我之前发现的,并非所有由 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) 创建的单元格都是可见的,我决定减少不知何故从 nib 文件加载新单元格的数量.为了实现这一点,我想到了一个简单的想法:为不可见的行返回空白的默认单元格,而为可见的行从 nib 加载自定义单元格.这是一段代码:

Secondly, as I discovered earlier, that not all cell are visible which are created by -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *), I decided to reduce somehow the number of loadings new cells from nib file. To achieve this, I've came to simple idea: return blank default cells for invisible rows, while load custom cells from nib for visible ones. Here is the piece of code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self index:indexPath isInvisibleInTableView:tableView])
        return [self getBlankCellForTableView:tableView];

    // the rest of the method is the same
    ...
}

-(BOOL)index:(NSIndexPath*)indexPath isInvisibleInTableView:(UITableView*)tableView
{
    NSMutableArray *visibleIndexPaths = [self getExtendedVisibleIndexPathsForTableView:tableView];

    return ![visibleIndexPaths containsObject:indexPath];
}

-(UITableViewCell*)getBlankCellForTableView:(UITableView*)tableView
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"IVBlankCell"];
    if (!cell)
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"IVBlankCell"] autorelease];

    return cell;
}

如您所见,我不只是使用 -(NSArray*)indexPathsForVisibleRows tableview 方法来检测可见单元格.相反,我编写了自己的方法 -(NSMutableArray*)getExtendedVisibleIndexPathsForTableView:(UITableView*)tableView.这是必要的,因为由于某种原因,当使用 -(NSArray*)indexPathsForVisibleRows 时,最后一个可见单元格旁边的单元格或第一个可见单元格之前的单元格被创建为空白单元格,滚动时看起来像空单元格.为了克服这个问题,在 -(NSMutableArray*)getExtendedVisibleIndexPathsForTableView: (UITableView*)tableView 中,我将边框单元格添加到可见数组单元格中:

As you can see, I'm not using just -(NSArray*)indexPathsForVisibleRows method of tableview for detecting visible cells. Instead, I've wrote my own method -(NSMutableArray*)getExtendedVisibleIndexPathsForTableView:(UITableView*)tableView. It was necessary because for some reason, when using -(NSArray*)indexPathsForVisibleRows the cells that are next to the last one visible cell or the cells that are previous to the first one visible cell were created as blank cells and looked like empty cells while scrolling. To overcome this, in -(NSMutableArray*)getExtendedVisibleIndexPathsForTableView: (UITableView*)tableView i'm adding border cells to the visible array cells:

-(NSMutableArray*)getExtendedVisibleIndexPathsForTableView:(UITableView*)tableView{
    NSArray *visibleIPs = [tableView indexPathsForVisibleRows];

    if (!visibleIPs || ![visibleIPs count])
        return [NSMutableArray array];

    NSIndexPath *firstVisibleIP = [visibleIPs objectAtIndex:0];
    NSIndexPath *lastVisibleIP = [visibleIPs objectAtIndex:[visibleIPs count]-1];

    NSIndexPath *prevIndex = ([firstVisibleIP row])?[NSIndexPath indexPathForRow:[firstVisibleIP row]-1  inSection:[firstVisibleIP section]]:nil;
    NSIndexPath *nextIndex = [NSIndexPath indexPathForRow:[lastVisibleIP row]+1 inSection:[lastVisibleIP section]];

    NSMutableArray *exVisibleIndexPaths = [NSMutableArray arrayWithArray:[tableView indexPathsForVisibleRows]];

    if (prevIndex)
        [exVisibleIndexPaths addObject:prevIndex];
    [exVisibleIndexPaths addObject:nextIndex];

    return exVisibleIndexPaths;
}

因此,我减少了打开具有大量自定义单元格的部分的时间,这在 Instruments 跟踪中得到了证明,并在体验应用程序时有所感受.

Thereby, I've reduced the time of opening sections with large number of custom cells, which was proved by Instruments tracing and felt while experiencing the app.

这篇关于tableView:cellForRowAtIndexPath:不仅为可见单元格调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆