2013-03-03 83 views
1

我完全难以解决如何解决此问题。 所以我有一个UITableView和委托方法cellForRowAtIndex:如果单元格为零(表视图的初始构建),我将向每个单元格添加几个子视图。一切运作良好,并建立了表视图,但是,当我在应用程序中向下滚动一下时,该应用程序突然与SIGBART崩溃并给我提供了错误 * 由于未捕获的异常'NSInvalidArgumentException' ,原因:'+ [NSIndexPath setImage:]:无法识别的选择器发送到类0x3c361e68' **这很奇怪,因为我甚至没有在我的代码中的任何地方调用setImage方法。 这是代表方法的代码。在滚动时向UITableViewCells添加子视图导致问题

- (UITableViewCell *)tableView:(UITableView *)tableView 
    cellForRowAtIndexPath:(NSIndexPath *)indexPath { 


static NSString *CellIdentifier = @"Cell"; 
UIImageView* imageView; 
UILabel* ttitle; 
UILabel* ttitle2; 
UILabel* ttitle3; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 

    // Configure cell: 
    // *** This section should configure the cell to a state independent of 
    // whatever row or section the cell is in, since it is only executed 
    // once when the cell is first created. 


    imageView=[[UIImageView alloc]initWithFrame:CGRectMake(10.0, 11.0, 50.0, 50.0)]; 
    [imageView setContentMode:UIViewContentModeScaleAspectFill]; 
    imageView.layer.masksToBounds=YES; 
    imageView.layer.cornerRadius=5.0; 
    [cell.contentView addSubview:imageView]; 

    ttitle = [[[UILabel alloc] initWithFrame:CGRectMake(70.0, 7.0, 200, 20)] autorelease]; 
    ttitle.textColor= [UIColor blackColor]; 
    ttitle.numberOfLines=1; 
    ttitle.backgroundColor=[UIColor clearColor]; 
    ttitle.font=[UIFont fontWithName:@"Arial Bold" size:15.0]; 
    [cell.contentView addSubview:ttitle]; 

    if (indexPath.row==0) { 

     CGSize size=[[[data objectAtIndex:indexPath.row] valueForKey:@"content"] sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:CGSizeMake(265.0f, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping]; 
     ttitle2 = [[[UILabel alloc] initWithFrame:CGRectMake(70.0, 27.5, 200, size.height)] autorelease]; 
     ttitle2.textColor= [UIColor darkGrayColor]; 
     ttitle2.backgroundColor=[UIColor clearColor]; 
     ttitle2.numberOfLines=0; 
     ttitle2.textAlignment = NSTextAlignmentLeft; 
     ttitle2.lineBreakMode=NSLineBreakByWordWrapping; 
     ttitle2.font=[UIFont fontWithName:@"Arial" size:14.0]; 
     [cell.contentView addSubview:ttitle2]; 

     ttitle3 = [[[UILabel alloc] initWithFrame:CGRectMake(70.0, ttitle2.frame.origin.y+ttitle2.frame.size.height-8.0, 210, 40)] autorelease]; 
     ttitle3.textColor= [UIColor darkGrayColor]; 
     ttitle3.backgroundColor=[UIColor clearColor]; 
     ttitle3.numberOfLines=1; 
     ttitle3.textAlignment = NSTextAlignmentLeft; 
     ttitle3.lineBreakMode=NSLineBreakByWordWrapping; 
     ttitle3.font=[UIFont fontWithName:@"Arial" size:11.0]; 
     [cell.contentView addSubview:ttitle3]; 


    } 
    else{ 

     CGSize size=[[[data objectAtIndex:indexPath.row] valueForKey:@"content"] sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:CGSizeMake(265.0f, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping]; 
     ttitle2 = [[[UILabel alloc] initWithFrame:CGRectMake(70.0, 27.0, 200, size.height)] autorelease]; 
     ttitle2.textColor= [UIColor darkGrayColor]; 
     ttitle2.backgroundColor=[UIColor clearColor]; 
     ttitle2.numberOfLines=0; 
     ttitle2.textAlignment = NSTextAlignmentLeft; 
     ttitle2.lineBreakMode=NSLineBreakByWordWrapping; 
     ttitle2.font=[UIFont fontWithName:@"Arial" size:14.0]; 
     [cell.contentView addSubview:ttitle2]; 


     ttitle3 = [[[UILabel alloc] initWithFrame:CGRectMake(70.0, ttitle2.frame.origin.y+ttitle2.frame.size.height-9.0, 210, 40)] autorelease]; 
     ttitle3.textColor= [UIColor darkGrayColor]; 
     ttitle3.backgroundColor=[UIColor clearColor]; 
     ttitle3.numberOfLines=1; 
     ttitle3.textAlignment = NSTextAlignmentLeft; 
     ttitle3.lineBreakMode=NSLineBreakByWordWrapping; 
     ttitle3.font=[UIFont fontWithName:@"Arial" size:11.0]; 
     [cell.contentView addSubview:ttitle3]; 

    } 

} 

// Customize cell: 
// *** This section should customize the cell depending on what row or section 
// is passed in indexPath, since this is executed every time this delegate method 
// is called. 
imageView.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[[data objectAtIndex:indexPath.row] valueForKey:@"thumbnail"]]]]; 

[ttitle setText:[[data objectAtIndex:indexPath.row] valueForKey:@"name"]]; 
[ttitle2 setText:[[data objectAtIndex:indexPath.row] valueForKey:@"content"]]; 

NSString* first=[[[data objectAtIndex:indexPath.row] valueForKey:@"hashtag"] stringByAppendingString:@"  "]; 
NSString* second =[first stringByAppendingString:[[data objectAtIndex:indexPath.row] valueForKey:@"place"]]; 
NSString* third=[second stringByAppendingString:@"  "]; 
NSString* fourth=[third stringByAppendingString:@"¤ "]; 
NSString* conversion=[[[data objectAtIndex:indexPath.row] valueForKey:@"counter"] stringValue]; 
NSString* fifth=[fourth stringByAppendingString:conversion]; 
[ttitle3 setText:fifth]; 





return cell; 

}

感谢帮助家伙!

*更新的代码

- (UITableViewCell *)tableView:(UITableView *)tableView 
    cellForRowAtIndexPath:(NSIndexPath *)indexPath { 


static NSString *CellIdentifier = @"Cell"; 
UIImageView* imageView; 
UILabel* ttitle; 
UILabel* ttitle2; 
UILabel* ttitle3; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 

    // Configure cell: 
    // *** This section should configure the cell to a state independent of 
    // whatever row or section the cell is in, since it is only executed 
    // once when the cell is first created. 


    imageView=[[UIImageView alloc]initWithFrame:CGRectMake(10.0, 11.0, 50.0, 50.0)]; 
    [imageView setContentMode:UIViewContentModeScaleAspectFill]; 
    imageView.layer.masksToBounds=YES; 
    imageView.layer.cornerRadius=5.0; 
    imageView.tag=1; 
    [cell.contentView addSubview:imageView]; 

    ttitle = [[[UILabel alloc] initWithFrame:CGRectMake(70.0, 7.0, 200, 20)] autorelease]; 
    ttitle.textColor= [UIColor blackColor]; 
    ttitle.numberOfLines=1; 
    ttitle.tag=69; 
    ttitle.backgroundColor=[UIColor clearColor]; 
    ttitle.font=[UIFont fontWithName:@"Arial Bold" size:15.0]; 
    [cell.contentView addSubview:ttitle]; 

    if (indexPath.row==0) { 

     CGSize size=[[[data objectAtIndex:indexPath.row] valueForKey:@"content"] sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:CGSizeMake(265.0f, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping]; 
     ttitle2 = [[[UILabel alloc] initWithFrame:CGRectMake(70.0, 27.5, 200, size.height)] autorelease]; 
     ttitle2.textColor= [UIColor darkGrayColor]; 
     ttitle2.backgroundColor=[UIColor clearColor]; 
     ttitle2.numberOfLines=0; 
     ttitle2.tag=70; 
     ttitle2.textAlignment = NSTextAlignmentLeft; 
     ttitle2.lineBreakMode=NSLineBreakByWordWrapping; 
     ttitle2.font=[UIFont fontWithName:@"Arial" size:14.0]; 
     [cell.contentView addSubview:ttitle2]; 

     ttitle3 = [[[UILabel alloc] initWithFrame:CGRectMake(70.0, ttitle2.frame.origin.y+ttitle2.frame.size.height-8.0, 210, 40)] autorelease]; 
     ttitle3.textColor= [UIColor darkGrayColor]; 
     ttitle3.backgroundColor=[UIColor clearColor]; 
     ttitle3.numberOfLines=1; 
     ttitle3.tag=71; 
     ttitle3.textAlignment = NSTextAlignmentLeft; 
     ttitle3.lineBreakMode=NSLineBreakByWordWrapping; 
     ttitle3.font=[UIFont fontWithName:@"Arial" size:11.0]; 
     [cell.contentView addSubview:ttitle3]; 


    } 
    else{ 

     CGSize size=[[[data objectAtIndex:indexPath.row] valueForKey:@"content"] sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:CGSizeMake(265.0f, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping]; 
     ttitle2 = [[[UILabel alloc] initWithFrame:CGRectMake(70.0, 27.0, 200, size.height)] autorelease]; 
     ttitle2.textColor= [UIColor darkGrayColor]; 
     ttitle2.backgroundColor=[UIColor clearColor]; 
     ttitle2.numberOfLines=0; 
     ttitle2.tag=70; 
     ttitle2.textAlignment = NSTextAlignmentLeft; 
     ttitle2.lineBreakMode=NSLineBreakByWordWrapping; 
     ttitle2.font=[UIFont fontWithName:@"Arial" size:14.0]; 
     [cell.contentView addSubview:ttitle2]; 


     ttitle3 = [[[UILabel alloc] initWithFrame:CGRectMake(70.0, ttitle2.frame.origin.y+ttitle2.frame.size.height-9.0, 210, 40)] autorelease]; 
     ttitle3.textColor= [UIColor darkGrayColor]; 
     ttitle3.backgroundColor=[UIColor clearColor]; 
     ttitle3.numberOfLines=1; 
     ttitle3.tag=71; 
     ttitle3.textAlignment = NSTextAlignmentLeft; 
     ttitle3.lineBreakMode=NSLineBreakByWordWrapping; 
     ttitle3.font=[UIFont fontWithName:@"Arial" size:11.0]; 
     [cell.contentView addSubview:ttitle3]; 

    } 

    imageView.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[[data objectAtIndex:indexPath.row] valueForKey:@"thumbnail"]]]]; 

    [ttitle setText:[[data objectAtIndex:indexPath.row] valueForKey:@"name"]]; 
    [ttitle2 setText:[[data objectAtIndex:indexPath.row] valueForKey:@"content"]]; 

    NSString* first=[[[data objectAtIndex:indexPath.row] valueForKey:@"hashtag"] stringByAppendingString:@"  "]; 
    NSString* second =[first stringByAppendingString:[[data objectAtIndex:indexPath.row] valueForKey:@"place"]]; 
    NSString* third=[second stringByAppendingString:@"  "]; 
    NSString* fourth=[third stringByAppendingString:@"¤ "]; 
    NSString* conversion=[[[data objectAtIndex:indexPath.row] valueForKey:@"counter"] stringValue]; 
    NSString* fifth=[fourth stringByAppendingString:conversion]; 
    [ttitle3 setText:fifth]; 


} 
else { 
    imageView =[cell viewWithTag:1]; 
    ttitle=[cell viewWithTag:69]; 
    ttitle2=[cell viewWithTag:70]; 
    ttitle3=[cell viewWithTag:71]; 
} 

//STUFFOUTSIDE 

// Customize cell: 
// *** This section should customize the cell depending on what row or section 
// is passed in indexPath, since this is executed every time this delegate method 
// is called. 



return cell; 

}

+0

这是一个内存管理问题。尝试使用僵尸工具运行 – Sven 2013-03-03 17:16:21

+3

不,实际上,它不是内存管理问题... – lnafziger 2013-03-03 17:32:39

+0

可能是配置自定义单元类然后调用它们获取一些indexPath值会更好吗? 希望这有助于! – 2013-03-03 17:23:16

回答

2

的问题是,当再次使用的电池的局部变量没有被初始化。下面是电流为ImageView的:

UIImageView* imageView; 

if (cell == nil) 
{ 
    // Create imageView 
    imageView=... 
} 

// If cell is being reused (ie cell is not nil) then imageView is nil at this point. 
imageView.image=... 

当你重复使用表格视图单元格,tableView:dequeueReusableCellWithIdentifier:返回一个实际的细胞,而不是nilimageView初始化被跳过。

您需要“查找”位于重用单元格中的imageView,以便对其进行更改。

因此,我建议你修改你的逻辑是这样的:

UIImageView* imageView; 

if (cell == nil) 
{ 
    // Create imageView 
    imageView=... 
} 
else 
{ 
    imageView = // get a reference to the imageView 
} 

imageView.image=... 

所以,现在,当然,问题是“怎么样?”。

一种非常常见的方式是在创建视图时设置该视图的tag,以便以后可以轻松检索该视图。你会使用这个技术是这样的:

// Use a unique tag number for each subview. 
#define MY_IMAGEVIEW_TAG 1000 

UIImageView* imageView; 

if (cell == nil) 
{ 
    // Create imageView 
    imageView=... // Same as before 
    imageView.tag = MY_IMAGEVIEW_TAG; 
} 
else 
{ 
    // This is a cell that is being re-used and was previously created. 
    // Retrieve a reference to the existing image view that is already in the cell 
    imageView = [cell viewWithTag:MY_IMAGEVIEW_TAG]; 
} 

// Now imageView is "safe" to use whether it is a new cell or one that is reused! 
imageView.image=... 

注:如果你是做了很多这方面,创造了UITableViewCell子类,具有属性每个子视图将使使用标签和viewWithTag不必要的,以及让您的代码更易于阅读。

+0

好吧,我明白你在做什么,它运作良好。唯一的情况是,有了这种方法,数据有时会重新排列。我的意思是tableView会重绘单元格出于某种原因(我没有得到,因为我通过使用这种类型的流程来避免这种冲突)。有任何想法吗? – user1493543 2013-03-03 17:55:16

+0

我在这里没有看到任何会改变你的数据源的东西。看看其他地方为什么发生这种情况! :-) – lnafziger 2013-03-03 18:20:25

+0

嗯,我不认为数据源正在改变,tableView只是重绘在不同位置的单元格。 – user1493543 2013-03-03 18:23:26

1

@Inafziger已经发布了这个问题的正确答案,我只是想详细解释一下为什么你会看到这个“奇怪”的崩溃。
虽然我不会推荐过多使用标签。创建一个UITableViewCell的子类可能是一个更好的主意。

你不初始化您imageViewttitle变量:

UIImageView *imageView; // imageView can point to anything now! 
UILabel* ttitle; 

通常情况下,你会初始化局部变量nil0(无论是有道理的),当你宣布他们避免这种悬摆指针。

因为你重用你的表视图细胞cell不会永远是nil和你的if子句不会被执行:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { // Won't be executed if the cell could be dequeued! 
    ... 
    imageView = ...; 
} 

因此,如果cell可以离队,你imageViewttitle当你使用它们时,变量还没有被分配给任何东西!

你再设置意见的属性:

imageView.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[[data objectAtIndex:indexPath.row] valueForKey:@"thumbnail"]]]]; 
[ttitle setText:[[data objectAtIndex:indexPath.row] valueForKey:@"name"]]; 
[ttitle2 setText:[[data objectAtIndex:indexPath.row] valueForKey:@"content"]] 

imageView.image = ...;是与调用[imageView setImage:...];。你可以在这里阅读更多关于:http://www.cocoacast.com/cocoacast/?q=node/103

而这就是当所有的一起:imageView没有初始化,你打电话-setImage:就可以了。轰隆,崩溃!

在你的情况下,imageView指向NSIndexPath类。不过,这可能是任何事情。
因此,您有效地在NSIndexPath类(相当于:+[NSIndexPath setImage:])上调用-setImage:,并且应用程序与+[NSIndexPath setImage:]: unrecognized selector sent to class 0x3c361e68错误消息崩溃。

+0

啊谢谢你的解释!但有一件事我不明白。当我们将子视图添加到UITableViewCells时,我们希望避免一遍又一遍地重复这些操作,因此每次重新使用单元格时都不会重新绘制这些对象。如果是这样,为什么这种方法不能正常工作?我实现了标签来创建子视图的引用,但tableView将从顶部的底部随机重绘单元格,反之亦然... – user1493543 2013-03-03 18:07:23

+0

请勿在'if(cell == nil)'子句中移动自定义代码。把它留在原来的位置,只添加'else {imageView = [cell viewWithTag:1]; ...}' – 2013-03-03 18:11:25

+0

对,我没有。 (发布上面的更新代码)。我只是不明白为什么tableView甚至会在这一点上做这样的事情。防爆。拿走最后一个单元格并在顶部重绘它。 – user1493543 2013-03-03 18:14:31