2012-10-05 37 views
4

我有一個相當密集的UITableView,需要稍微優化。問題是,如何使用大中央電臺有效地做到這一點。每個單元格都有一個帶有一對標籤和兩個圖像的UIView。我已經將TableViewCell分類了,並且視圖被重用,儘管當表變大時它仍然有點滯後。我將如何使用GCD來優化表格?還是有更好的方法嗎?我在線程管理方面不是很強大,並且尋求一些建議。iOS GCD用於UITableView

下面是代碼我的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; 
} 

這裏是子類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]; 
    } 
} 
+0

是[xmlParser調用]每次解析xml嗎?你的代碼似乎沒有其他任何東西需要線程化。圖像是本地的,操作是標準的。 XML解析是昂貴的,所以這就是爲什麼我想知道。如果是這樣,那麼解析一次並將數組存儲在某個地方,這樣就可以調用objectAtIndex。 – Matt

+0

解析器每次調用刷新時都會運行,方法是拉下表視圖。 XML是動態的,所以它不斷變化,這就是爲什麼用戶有能力刷新。我已經建立了解析器,使用GCD在後臺運行,這有點幫助。解析器僅在刷新方法被調用並且數據存儲在數組中時才運行。我只是擔心這些觀點正在放慢速度。 –

+0

好的,你仍然要確保它每次刷新只解析一次。我沒有從你的迴應中得知這個函數調用是否導致了一個解析操作,但是如果是這樣的話,它將解析表中的任意多個單元格,並且我猜你正在確定[ xmlParser調用] count]。但是,是的,在背景上進行解析是正確的方法。爲了安全起見,您應該在解析發生時顯示某種活動單元格(以防萬一)。在用戶刷新時調用reloadData,並在解析完成時再次調用...但在主線上。 – Matt

回答

3

這有點微妙,但主要的區域代碼將掛起on在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有什麼關係,但希望這可以解決您的問題,而不用使用大錘來破解堅果:)。