tableView:cellForRowAtIndexPath:调用不仅为可见的单元格?

我有一个tableView的部分,可以打开和closures。 所以,当我点击一个部分打开它,它正在满足细胞和-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)被调用的次数正如我提供的-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

那是对的吗? 它不应该只是可见细胞的数量吗?

因为在我的情况下,我有不好的情况:我有很多自定义单元格-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)单元格)和调用-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)为每个单元格放慢打开一个部分,导致每次从笔尖读取并且单元格内容被填充图像。 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)像这样:

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

这表明从45个单元中只有6个或7个是可见的。 其他人不在可见范围内。 但是创build单元格仍然执行。 这里是代码:

 -(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; } 

这是否正确? 还是我错过了什么?

那么,我不知何故处理我的问题。 这是我的想法和想法如何来解决scheme。 也许这可能对某人有所帮助。

我已经在开幕式的事件中指示了内存分配和调用堆栈。 它告诉我,大部分时间都花在从nib文件加载单元格上。

首先,我所做的是减小nib文件的大小 ,即最小化自定义tableview单元格(现在只有2个视图和2个标签,而不是6个视图,2个图像和2个标签之前)使用的视图数量。 它给了我一些细胞加载的改善。 苹果的文档build议使用尽可能less的意见,不要使用透明度。 所以要注意这些build议。

其次,正如我前面发现,并不是所有单元格是由-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)创build的可见,我决定减less从nib文件加载新单元格的数量。 为了达到这个目的,我想到了一个简单的想法:为不可见行返回空白默认单元格,同时从可见部分加载自定义单元格。 这是一段代码:

 - (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; } 

正如你所看到的,我不只是使用tableview的-(NSArray*)indexPathsForVisibleRows方法来检测可见的单元格。 相反,我写了自己的方法-(NSMutableArray*)getExtendedVisibleIndexPathsForTableView:(UITableView*)tableView 。 这是必要的,因为某些原因,当使用-(NSArray*)indexPathsForVisibleRows ,最后一个可见单元格旁边的单元格或第一个可见单元格之前的单元格被创build为空白单元格,而看起来像空单元格滚动。 为了解决这个问题,在-(NSMutableArray*)getExtendedVisibleIndexPathsForTableView: (UITableView*)tableView我将边框单元格添加到可见的数组单元格:

 -(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; } 

因此,我减less了大量的自定义单元打开部分的时间,这是通过仪器跟踪,体验应用程序时感受到的。

检查你的tableview大小。 可能是你的tableview高度是非常大的,它不断加载单元格,直到你的单元格填充所有的tableview大小..

这似乎是正确的。 关于优化加载本身的想法在于“dequeueReusableCellWithIdentifier”是如何工作的。 如果你从远程位置加载图像,这是你想要优化代码的地方。 但不是从单元格加载,因为这看起来是正确的。

我使用了一些类似的技术,但自indexPathsForVisibleRowssorting你不需要使用containsObject。 相反,你可以做:

 // // Checks if indexPath is visible in current scroll state, we are expanding bounds by 1 // because the cells that are next to the last one visible or the cells that are previous // to the first one visible could look empty while scrolling. // - (BOOL)isIndexPathVisible:(NSIndexPath *)indexPath { NSInteger row = [indexPath row]; NSArray *visible = [self.tableView indexPathsForVisibleRows]; NSInteger count = [visible count]; NSInteger first = (count > 0) ? MAX([visible[0] row] - 1, 0): 0; NSInteger last = (count > 1) ? [visible[1] row] + 1: first + 2; return row >= first && row <= last; } 

顺便一提; 这假定您只使用一个部分。 它不适用于多个部分。

添加一个别人解决了我的问题。 我在哪里重新设置了对单元格的任何更改。

 if (! self.cell) { self.cell = [[LanguageCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; self.cell.accessoryType = UITableViewCellAccessoryNone; } else { self.cell.checkImage.image = NO; }