4

少し最適化する必要があるかなり集中的なUITableViewがあります。問題は、それを効果的に行うためにグランドセントラル駅をどのように使用するかです。各セルには、2つのラベルと2つの画像を含むUIViewがあります。TableViewCellをサブクラス化し、テーブルが大きくなったときにまだ少し遅れていますが、ビューは再利用されています。GCDを使用してテーブルを最適化するにはどうすればよいですか?またはそれを回避するより良い方法はありますか?私はスレッド管理にあまり強くなく、アドバイスを探しています。

これが私のテーブルビューのコードです:

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

static NSString *CellIdentifier = @"Cell";
JointCAD *currentCall = [[xmlParser calls] objectAtIndex:indexPath.row];
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"texture3.png"]];

TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
{
    cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

cell.callTypeLabel.text = currentCall.currentCallType;
cell.locationLabel.text = currentCall.location;
cell.unitsLabel.text = currentCall.units;
cell.stationLabel.text = [@"Station: " stringByAppendingString:currentCall.station];
cell.selectedBackgroundView = cell.selectionView;

if ([currentCall.callType isEqualToString:@"F"]) {
    cell.imageType = Fire;
}
else {
    cell.imageType = EMS;
}

if ([currentCall.county isEqualToString:@"W"]) {
    cell.imageType1 = Washington;
}
else {
    cell.imageType1 = Clackamas;
}

return cell;
}

サブクラス化されたtableviewcellは次のとおりです。

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {

    callView = [[UIView alloc] initWithFrame:CGRectMake(7.5, 7, 305, 65)];
    [callView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin |
     UIViewAutoresizingFlexibleRightMargin |
     UIViewAutoresizingFlexibleWidth];
    [callView setContentMode:UIViewContentModeTopLeft];
    [callView setBackgroundColor: [UIColor colorWithRed:240.0/255.0 green:240.0/255.0 blue:240.0/255.0 alpha:1.0]];
    callView.layer.borderWidth = 1.0;
    callView.layer.borderColor = [UIColor colorWithRed:(0/255.0)  green:(0/255.0)  blue:(0/255.0)  alpha:1.0].CGColor;

    [self.contentView addSubview:callView];

    callTypeLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 2, 190, 21)];
    callTypeLabel.font = [UIFont boldSystemFontOfSize:12.0];
    callTypeLabel.textColor = [UIColor blackColor];
    callTypeLabel.backgroundColor = [UIColor clearColor];
    callTypeLabel.highlightedTextColor = [UIColor whiteColor];
    callTypeLabel.adjustsFontSizeToFitWidth = YES;
    [callView addSubview:callTypeLabel];

    locationLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 17 , 190, 15)];
    locationLabel.font = [UIFont systemFontOfSize:10.0];
    locationLabel.textColor = [UIColor blackColor];
    locationLabel.backgroundColor = [UIColor clearColor];
    locationLabel.highlightedTextColor = [UIColor whiteColor];
    locationLabel.adjustsFontSizeToFitWidth = YES;
    [callView addSubview:locationLabel];

    unitsLabel = [[UILabel alloc]initWithFrame:CGRectMake(4, 43, 190, 21)];
    unitsLabel.font = [UIFont systemFontOfSize:10.0];
    unitsLabel.textColor = [UIColor blackColor];
    unitsLabel.backgroundColor = [UIColor clearColor];
    unitsLabel.highlightedTextColor = [UIColor whiteColor];
    unitsLabel.adjustsFontSizeToFitWidth = NO;
    [callView addSubview:unitsLabel];

    stationLabel = [[UILabel alloc]initWithFrame:CGRectMake(195 , 25, 75, 20)];
    stationLabel.font = [UIFont systemFontOfSize:12.0];
    stationLabel.textColor = [UIColor blackColor];
    stationLabel.backgroundColor = [UIColor clearColor];
    stationLabel.highlightedTextColor = [UIColor whiteColor];
    stationLabel.adjustsFontSizeToFitWidth = YES;
    [callView addSubview:stationLabel];

    CGRect countyImageFrame = CGRectMake(275, 10, 18, 18);
    UIImageView *countyImageView = [[UIImageView alloc] initWithFrame:countyImageFrame];
    countyImageView.image = countyImage;
    [callView addSubview:countyImageView];

    CGRect callTypeImageFrame = CGRectMake(275, 37, 18, 18);
    UIImageView *callTypeImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
    callTypeImageView.image = callTypeImage;
    [callView addSubview:callTypeImageView];

    selectionView = [[UIView alloc] initWithFrame:CGRectMake(10, 7, 200, 65)];
    [selectionView setBackgroundColor: [UIColor clearColor]];

    }

    return self;
}

- (void)setImageType:(CallType)newImageType {
imageType = newImageType;

if (imageType == Fire) {
    CGRect callTypeImageFrame = CGRectMake(275, 37, 18, 18);
    UIImageView *callTypeImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
    callTypeImageView.image = [UIImage imageNamed:@"red.png"];
    [callView addSubview:callTypeImageView];
}
else if (imageType == EMS) {
    CGRect callTypeImageFrame = CGRectMake(275, 37, 18, 18);
    UIImageView *callTypeImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
    callTypeImageView.image = [UIImage imageNamed:@"yellow.png"];
    [callView addSubview:callTypeImageView];
    }
}

- (void)setImageType1:(County)newImageType1 {
imageType1 = newImageType1;

if (imageType1 == Washington) {
    CGRect callTypeImageFrame = CGRectMake(275, 10, 18, 18);
    UIImageView *countyImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
    countyImageView.image = [UIImage imageNamed:@"blue.png"];
    [callView addSubview:countyImageView];
}
else if (imageType1 == Clackamas) {
    CGRect callTypeImageFrame = CGRectMake(275, 10, 18, 18);
    UIImageView *countyImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
    countyImageView.image = [UIImage imageNamed:@"green.png"];
    [callView addSubview:countyImageView];
    }
}
4

1 に答える 1

3

これは少しわかりにくいですが、コードがハングアップする主な領域は setImageType: メソッドです。

ここで、プログラムで作成されたイメージ ビューをビュー階層に追加します。

UIImageView *callTypeImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
callTypeImageView.image = [UIImage imageNamed:@"red.png"];
[callView addSubview:callTypeImageView];

しかし、古い画像ビューを実際に削除することはありません。これを行うためのより良い方法は、作成された画像ビューをセルのプロパティにキャッシュし、画像タイプを設定するときに、新しい画像ビューを作成する前に古い画像ビューに [UIView removeFromSuperview] メッセージを送信することです。

現在のコードでは、セルがデキューされるたびに新しい画像ビューが追加されるため、ユーザーがテーブル ビューを上下にスクロールするたびに、新しい画像ビューが作成されてセルに追加されます。各セルに数十の画像ビューが表示されるまで、それほど時間はかかりません。これにより、目的を達成するために実際に必要な数よりも多くの drawRect が画像ビューに呼び出されていると思われます。

これを行うためのより良い方法は、セルの init メソッドで作成するプロパティとして両方のタイプの画像ビューを使用することです。これらは setType メソッドでのみ構成されます。そうすれば、タイプごとに 1 つのイメージ ビューのみを作成し、適切な setType メソッドでそのイメージを設定するだけです。このようにすると、removeFromSuperview は imageview を解放するので、それを強力なプロパティとして宣言する必要があることに注意してください (ARC を使用している場合)。

これらの解決策のどちらもGrand Central Dispatchとは何の関係もないことを理解していますが、大ハンマーを使用してナットを割ることなく問題を解決できることを願っています:)。

于 2012-12-05T11:43:05.800 に答える