滚动表格视图时应用程序崩溃
Posted
技术标签:
【中文标题】滚动表格视图时应用程序崩溃【英文标题】:App crashing when scrolling table view 【发布时间】:2011-06-23 19:47:47 【问题描述】:在我的应用程序中,我有一个表格视图在一行中显示图像视图,4 个图像视图。我的问题是,在使用一些数据加载表格视图之后,如果我尝试滚动表格视图,那么我的应用程序就会崩溃。在使用断点时,我发现再次调用索引路径方法中的行单元格,并且我的数组尝试再次重新加载数据。请帮助,因为它现在让我头疼,我在这里发布我的代码:--
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = @"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier] autorelease];
UIImageView * imageView1 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 70, 80)] autorelease];
UIImageView * imageView2 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,70, 80)] autorelease];
UIImageView * imageView3 = [[[UIImageView alloc] initWithFrame:CGRectMake(205,4, 70, 80)] autorelease];
UIImageView * imageView4 = [[[UIImageView alloc] initWithFrame:CGRectMake(295,4, 70, 80)] autorelease];
UIImageView * imageView5 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 70, 80)] autorelease];
UIImageView * imageView6 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,70, 80)] autorelease];
UIImageView * imageView7 = [[[UIImageView alloc] initWithFrame:CGRectMake(205,4, 70, 80)] autorelease];
UIImageView * imageView8 = [[[UIImageView alloc] initWithFrame:CGRectMake(295,4, 70, 80)] autorelease];
UIImageView * imageView9 = [[[UIImageView alloc] initWithFrame:CGRectMake(25, 4, 70, 80)] autorelease];
UIImageView * imageView10 = [[[UIImageView alloc] initWithFrame:CGRectMake(115,4,70, 80)] autorelease];
UIImageView * imageView11 = [[[UIImageView alloc] initWithFrame:CGRectMake(205,4, 70, 80)] autorelease];
UIImageView * imageView12 = [[[UIImageView alloc] initWithFrame:CGRectMake(295,4, 70, 80)] autorelease];
imageView1.tag=1;
imageView2.tag=2;
imageView3.tag=3;
imageView4.tag=4;
imageView5.tag=5;
imageView6.tag=6;
imageView7.tag=7;
imageView8.tag=8;
imageView9.tag=9;
imageView10.tag=10;
imageView11.tag=11;
imageView12.tag=12;
if ([sentence count]>0)
[imageViewArray insertObject:imageView1 atIndex:0];
[cell.contentView addSubview:imageView1];
if ([sentence count]>1)
[imageViewArray insertObject:imageView2 atIndex:1];
[cell.contentView addSubview:imageView2];
if ([sentence count]>2)
[imageViewArray insertObject:imageView3 atIndex:2];
[cell.contentView addSubview:imageView3];
if ([sentence count]>3)
[imageViewArray insertObject:imageView4 atIndex:3];
[cell.contentView addSubview:imageView4];
if ([sentence count]>4)
[imageViewArray insertObject:imageView5 atIndex:4];
[cell.contentView addSubview:imageView5];
if ([sentence count]>5)
[imageViewArray insertObject:imageView6 atIndex:5];
[cell.contentView addSubview:imageView6];
if ([sentence count]>6)
[imageViewArray insertObject:imageView7 atIndex:6];
[cell.contentView addSubview:imageView7];
if ([sentence count]>7)
[imageViewArray insertObject:imageView8 atIndex:7];
[cell.contentView addSubview:imageView8];
if ([sentence count]>8)
[imageViewArray insertObject:imageView9 atIndex:8];
[cell.contentView addSubview:imageView9];
if ([sentence count]>9)
[imageViewArray insertObject:imageView10 atIndex:9];
[cell.contentView addSubview:imageView10];
if ([sentence count]>10)
[imageViewArray insertObject:imageView11 atIndex:10];
[cell.contentView addSubview:imageView11];
if ([sentence count]>11 || ([sentence count]==12))
[imageViewArray insertObject:imageView12 atIndex:11];
[cell.contentView addSubview:imageView12];
if ([sentence count]!=0)
int photosInRow;
if ( (indexPath.row <
[tableView numberOfRowsInSection:indexPath.section] - 1) || ([sentence count] % 4 == 0) )
photosInRow = 4;
else
photosInRow = [sentence count] % 4;
for ( int i = 1; i <=photosInRow ; i++ )
imageView = (UIImageView *)[cell.contentView viewWithTag:j];
[self setImage1:imageView];
return cell;
【问题讨论】:
经过 72 个问题,我想一个人会弄清楚如何正确格式化代码。 【参考方案1】:我相信这里最大的问题是 imageViews 的内存泄漏。每个单元格创建 12 个 imageView,没有一个被释放。看来你应该只创建你需要的图像视图(为了速度),并正确释放它们(为了内存管理)。
开始重写此代码的一种方法如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *AutoCompleteRowIdentifier = @"AutoCompleteRowIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (!cell)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier] autorelease];
for (int i=0; i <= [sentence count]; ++i)
UIImageView * imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(25+90*(i%4), 4, 70, 80)] autorelease];
imageView.tag = i+1;
[cell.contentView addSubview:imageView];
[imageView release];
return cell;
我不明白你为什么要反复设置imageViewArray
或imageView1
。另外,这一行:
imageView = (UIImageView *)[cell.contentView viewWithTag:j];
没有意义,因为 j
没有定义。
【讨论】:
非常感谢,从现在开始我会处理代码格式 @Christina:它所以更容易阅读。另外,不要害怕for
循环......它们使您的代码更易于阅读和编辑,因此从长远来看应该可以为您节省大量时间。
但是当我滚动表格视图时我的应用程序仍然崩溃【参考方案2】:
在使用断点时,我发现索引路径方法的行单元格被再次调用,我的数组再次尝试重新加载数据。
没错。如果你不明白这一点,你就不会明白表格视图是如何工作的。单元是按需创建并重复使用的;当用户滚动时,相同的单元格可能会一次又一次地重复用于表格的不同行。这意味着您必须事先准备所有数据,然后简单地按需为请求的任何部分/行获取数据。
换句话说,MVC:模型-视图-控制器。你的模型就是你的数据。 tableView:cellForRowAtIndexPath:
是视图;在此期间您不得修改模型,因为调用它的时间和频率完全取决于视图的需要。
另一件事是您不应该制作单独的图像视图数组。图像视图是视图。如果您想存储某物的列表,请存储图像名称或某物的列表。
【讨论】:
以上是关于滚动表格视图时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章