Using iOS GCD for UITableView

I have a pretty intense UITableView that needs to be optimized a bit. The question is how to use the central central station to do this efficiently. Each cell has a UIView with two labels and two images. I have subclassed TableViewCell and the view is reused, although it is still slightly behind when the table gets larger. How can I use GCD to optimize a table? OR is there a better way around this? I am not very good at managing flows and I am looking for some advice.

Here is the code for my table:

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

Here are the subclasses of 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
source share
1 answer

This is a bit subtle, but the main area your code will hang on is in the setImageType: method.

You add the programmatically created Image View to your view hierarchy here:

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

But you never delete the old image. The best way to do this is to cache the created image view in the cell property, and then when you set the image type, send a message - [UIView removeFromSuperview] to the old image view before creating a new one.

When your code is standing now, every time a cell is deleted, a new image view is added to it, so every time the user scrolls up and down the table view, a new image is created and added to the cell. Each cell will not have many dozens of images. I suspect that this raises many times more drawRect calls in image representations than is really necessary to achieve your goal.

The best way to do this would be to have both types of image representations as properties that you create in the init method of the cell, which are set only in the setType methods. Thus, you create only one type of image for each type and simply set its image in the corresponding setType method. Do it this way, remember that removeFromSuperview will free the image, so you have to declare it as a strong property (assuming you use ARC).

I understand that none of these solutions has anything to do with Grand Central Dispatch, but I hope this should solve your problem without using a sledgehammer to crack the nut :).

+3
source

Source: https://habr.com/ru/post/1438071/


All Articles