Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS GCD用于UITableView_Ios_Multithreading_Tableview_Grand Central Dispatch - Fatal编程技术网

iOS GCD用于UITableView

iOS GCD用于UITableView,ios,multithreading,tableview,grand-central-dispatch,Ios,Multithreading,Tableview,Grand Central Dispatch,我有一个非常密集的UITableView,需要稍微优化一下。问题是,如何有效地利用中央车站。每个单元格都有一个UIView,其中包含两个标签和两个图像。我已经对TableViewCell进行了子类化,视图被重用,尽管当表变大时它仍然有点滞后。我如何使用GCD来优化表格?还是有更好的解决办法?我不是很强的线程管理和寻求一些建议 以下是我的tableview的代码: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowA

我有一个非常密集的UITableView,需要稍微优化一下。问题是,如何有效地利用中央车站。每个单元格都有一个UIView,其中包含两个标签和两个图像。我已经对TableViewCell进行了子类化,视图被重用,尽管当表变大时它仍然有点滞后。我如何使用GCD来优化表格?还是有更好的解决办法?我不是很强的线程管理和寻求一些建议

以下是我的tableview的代码:

- (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;
}
- (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];
    }
}
下面是子类tableviewcell:

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

这有点微妙,但代码将挂起的主要区域是setImageType:方法

您正在将以编程方式创建的图像视图添加到视图层次结构中,如下所示:

UIImageView *callTypeImageView = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
callTypeImageView.image = [UIImage imageNamed:@"red.png"];
[callView addSubview:callTypeImageView];
但您从未实际删除旧的图像视图。更好的方法是将创建的图像视图缓存在单元格的属性中,然后在设置图像类型时,在创建新图像视图之前,将消息-[UIView removeFromSuperview]发送到旧图像视图

正如您现在的代码所示,每次单元格出列时,都会向其添加一个新的图像视图,因此每次用户上下滚动表视图时,都会创建一个新的图像视图并将其添加到单元格中。每个单元格中都会有几十个图像视图,这不会花费很长时间。我怀疑这会导致对图像视图的drawRect调用比实现您的目的实际需要的要多出很多倍

更好的方法是将这两种类型的图像视图都作为属性,您可以在单元格的init方法中创建这些属性,这些属性仅在setType方法中配置。这样,每个类型只创建一个图像视图,只需在适当的setType方法中设置并配置其图像。这样做时,请记住removeFromSuperview将释放imageview,因此您必须将其声明为强属性(假设您使用的是ARC)


我理解这两种解决方案都与Grand Central Dispatch无关,但希望这能解决您的问题,而不必使用大锤敲碎螺母:)。

每次[xmlParser calls]都在解析xml吗?您的代码似乎不需要线程。图像是本地的,操作是标准的。XML解析成本很高,所以我想知道。如果是,则解析它一次并将数组存储在某个位置,这样您就可以在该位置上调用objectAtIndex。每次调用刷新时,解析器都会运行,方法是下拉表视图。XML是动态的,因此它是不断变化的,这就是用户能够刷新的原因。我已经使用GCD设置了在后台运行的解析器,这有一点帮助。解析器仅在调用refresh方法并且数据存储在数组中时运行。我只是担心视图会减慢它的速度。好的,您仍然希望确保每次刷新只解析一次。我没有从您的响应中得到该函数调用是否导致了解析操作,但如果是这样,它将解析表中相同数量的单元格,我猜您也在使用[[xmlParser calls]count]确定单元格的数量。但是,在后台进行解析是正确的方法。为了安全起见,您应该在解析过程中显示某种类型的活动单元格(以防万一)。当用户刷新时调用reloadData,当解析完成时再次调用reloadData。。。但是在主线程上,调用不是函数,而是存储表数据的数组。当下拉启动时,XML解析器只运行一次。一旦解析器完成,数据输入到数组中,就会调用表reloadData。对于有趣的“Grand Central Station”而不是“Grand Central Dispatch”,调用+1