2013-03-03 78 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