1

私はこの問題を修正する方法に絶対に困惑しています。したがって、UITableViewがあり、デリゲートメソッドcellForRowAtIndexにあります。セルがnil(テーブルビューの最初の構築)の場合、各セルにいくつかのサブビューを追加しています。すべてが正常に機能し、テーブルビューが構築されますが、アプリケーションを少し下にスクロールすると、アプリが突然SIGBARTでクラッシュし、エラーが発生します *キャッチされなかった例外'NSInvalidArgumentException'、理由:'+ [NSIndexPath setImage:]:認識されないセレクターがクラス0x3c361e68に送信されたためにアプリを終了しています' **コードのどこにもsetImageメソッドを呼び出していないため、奇妙です。デリゲートメソッドのコードは次のとおりです。

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

}

4

2 に答える 2

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:の代わりに実際のセルを返し、nilの初期化imageViewはスキップされます。

変更を加えるには、再利用されたセルにある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を使用する必要がなくなり、コードが読みやすくなります。

于 2013-03-03T17:39:45.970 に答える
1

@Inafziger は、この質問に対する正しい回答を既に投稿しています。この「奇妙な」クラッシュが発生する理由をもう少し詳しく説明したいと思います。
ただし、タグを過度に使用することはお勧めしません。のサブクラスを作成することをお勧めしますUITableViewCell

imageView変数と変数を初期化していませんttitle:

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

通常、ローカル変数をnilor 0(意味のあるものは何でも) に初期化して、そのようなダングリング ポインターを回避します。

テーブル ビューのセル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ただし、これは何でもかまいません。そのため、効果的にクラス (: と同等) を
呼び出しており、アプリがクラッシュしてエラー メッセージが表示されます。-setImage:NSIndexPath+[NSIndexPath setImage:]+[NSIndexPath setImage:]: unrecognized selector sent to class 0x3c361e68

于 2013-03-03T17:58:15.340 に答える