博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS UITableView详解二性能优化 & LOL游戏人物展示
阅读量:6846 次
发布时间:2019-06-26

本文共 9872 字,大约阅读时间需要 32 分钟。

  hot3.png

一 重用UITableViewCell

UITableView滑动过程中,屏幕底部的信息上移到屏幕,会创建UITableViewCell对象,当把头部的信息再下拉重回到屏幕时,UITableViewCell会重复创建。重复创建会消耗内存,影响性能,通过重用UITableViewCell机制,能有效的避免性能问题。

1.1 不良代码
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    /*************第一版 Car *****************/     //1.创建cell     //当cell出现在屏幕时会重建     UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];          cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;          //2.取出数据     GMCar *car = self.array[indexPath.section];     NSString *name =car.subCars[indexPath.row];          //3.设置数据     cell.textLabel.text =name;          return cell;}

1.2 重用Cell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{     /*************第二版 LOL*****************/    //1.缓冲池中找cell是否已经创建,避免重建    static NSString * identifier = @"lol";    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];        //2.如果缓冲池中没有就创建cell    if (cell == nil) {        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];        //NSLog(@"create new cell");    }        //3.设置数据    GMLOL  *lol = self.dataArray[indexPath.row];        cell.textLabel.text = lol.name;    cell.textLabel.font = GMTextFont;            cell.detailTextLabel.text = lol.intro;    cell.detailTextLabel.font = GMDetailTextFont;    cell.detailTextLabel.numberOfLines=0;            cell.imageView.image = [UIImage imageNamed:lol.icon];                return cell;}

注:申请内存需要时间,特别是在一定时间内频繁的申请内存将会造成很大的开销,重用UITableViewCell是UITableView dataSource中需要重点注意的地方,采用重用机制会让tableView更加流畅。

二 避免UITavleViewCell contentView 重新布局

UITableViewCell 在创建时就要将布局布好,避免 UITableViewCell 的重新布局。

三 避免UITavleViewCell 子视图过多 和 视图渲染

添加的UITableViewCell的子视图不宜过多(>4),过多的子视图对效率会参数影响。最好设置子视图为不透明的(opaque为YES),因为如果 子视图 不是 不透明的,view图层的叠加会开销一定的时间,影响到UITableView运行效率。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{        //1.缓冲池中找    static NSString * identifier = @"lol";    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];        //2.如果缓冲池中没有就创建cell    if (cell == nil) {        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];    }        //3.设置子视图    CGFloat padding =10;    CGFloat labelW = 20;    CGFloat labelH = 30;    CGFloat labelY = 0;        for (int i=0; i<=10; i++) {        UILabel *label = [[UILabel alloc] init];                //设置文本位置        label.frame = CGRectMake((labelW+padding)*i, labelY, labelW, labelH);                //设置背景颜色        label.backgroundColor = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];                //设置文本内容        label.text = [NSString stringWithFormat:@"%d",i];        label.opaque = YES;//默认是YES                        [cell.contentView addSubview:label];    }        return cell;}

    子视图小于3时顺畅                                 子视图为10时,拖拽界面有点颠簸

   182446_eqc1_1032974.png                181812_Fptr_1032974.png

四 LOL 代码区

注意点: UITableViewCell 重用,根据文本高度设置Cell

4.1代码
// ===== lol 类@interface GMLOL : NSObject@property (nonatomic, copy) NSString *icon;@property (nonatomic, copy) NSString *name;@property (nonatomic, copy) NSString *intro;-(instancetype)initWithDict:(NSDictionary *)dict;+(instancetype)lolWithDict:(NSDictionary *)dict;@end@implementation GMLOL-(instancetype)initWithDict:(NSDictionary *)dict{    if (self = [super init]) {        [self setValuesForKeysWithDictionary:dict];    }    return self;}+(instancetype)lolWithDict:(NSDictionary *)dict{    return [[self alloc]initWithDict:dict];}@end

#import "ViewController.h"#import "GMCar.h"#import "GMLOL.h"#define GMTextFont [UIFont systemFontOfSize:20]#define GMDetailTextFont [UIFont systemFontOfSize:13]@interface ViewController ()
/** *  UITableView */@property (nonatomic, strong) UITableView *tableView;/** *  car 数组 */@property (nonatomic, strong) NSArray *array;/** *  lol 数组 */@property (nonatomic, strong) NSArray *dataArray;@end@implementation ViewController- (void)viewDidLoad {    /*************第一版 Car *****************/    /*     //1.UITableView 设置     //1.1 设置数据代理     self.tableView.dataSource = self;     //1.2 设置frame     self.tableView.frame = self.view.frame;     //1.3 设置代理     self.tableView.delegate = self;          //2.UITableView加入veiw     [self.view addSubview:self.tableView];     */        /*************第二版 LOL*****************/        //1.UITableView 设置    //1.1 设置数据代理    self.tableView.dataSource = self;    //1.2 设置frame    self.tableView.frame = self.view.frame;    //1.3 设置代理    self.tableView.delegate = self;        //2.UITableView加入veiw    [self.view addSubview:self.tableView];}#pragma mark - 数据加载/** *  调用数据源以下方法获取一共有多少组数据 * *  @param tableView <#tableView description#> * *  @return <#return value description#> */-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    /*************第一版 Car *****************/    //return self.array.count;        /*************第二版 LOL*****************/    return 1;}/** *  调用数据源方法获取每一组有多少行数据 * *  @param tableView tableView description *  @param section   <#section description#> * *  @return <#return value description#> */-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    /*************第一版 Car *****************/    //GMCar *car = self.array[section];    //return car.subCars.count;            /*************第二版 LOL*****************/    return self.dataArray.count;}/** *  调用数据源方法获取每一行显示什么内容 * *  @param tableView <#tableView description#> *  @param indexPath <#indexPath description#> * *  @return <#return value description#> */-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    /*************第一版 Car *****************/    /*     //1.创建cell     UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];          cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;          //2.取出数据     GMCar *car = self.array[indexPath.section];     NSString *name =car.subCars[indexPath.row];          //3.设置数据     cell.textLabel.text =name;     */            //性能改进        /*************第二版 LOL*****************/    //1.缓冲池中找    static NSString * identifier = @"lol";    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];        //2.如果缓冲池中没有就创建cell    if (cell == nil) {        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];        //NSLog(@"create new cell");    }        //3.设置数据    GMLOL  *lol = self.dataArray[indexPath.row];        cell.textLabel.text = lol.name;    cell.textLabel.font = GMTextFont;            cell.detailTextLabel.text = lol.intro;    cell.detailTextLabel.font = GMDetailTextFont;    cell.detailTextLabel.numberOfLines=0;            cell.imageView.image = [UIImage imageNamed:lol.icon];                return cell;}#pragma mark - UITableViewDelegate/** *  table 每一行的高度 * *  @param tableView <#tableView description#> *  @param indexPath <#indexPath description#> * *  @return <#return value description#> */-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    //计算行高    CGFloat padding =20;        GMLOL  *lol = self.dataArray[indexPath.row];    CGSize nameSzie = [self sizeWithString:lol.name font:GMTextFont maxSize:CGSizeMake(300, MAXFLOAT)];    CGSize detailSzie = [self sizeWithString:lol.intro font:GMDetailTextFont maxSize:CGSizeMake(300, MAXFLOAT)];        return  nameSzie.height + detailSzie.height +padding;}#pragma mark - 懒加载-(UITableView *)tableView{    if (!_tableView) {        //UITableViewStyleGrouped样式        //_tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStyleGrouped];        //UITableViewStylePlain 样式        _tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStylePlain];    }    return _tableView;}-(NSArray *)array{    if (!_array) {        _array = [[NSArray alloc]init];        GMCar *c1 = [[GMCar alloc] init];        c1.title = @"德国品牌";        c1.desc = @"世界一流品牌";        c1.subCars = @[@"奥迪" , @"宝马"];                GMCar *c2 = [[GMCar alloc] init];        c2.title = @"日本品牌";        c2.desc = @"实用价值高";        c2.subCars = @[@"丰田" , @"本田"];                GMCar *c3 = [[GMCar alloc] init];        c3.title = @"欧美品牌";        c3.desc = @"高逼格";        c3.subCars = @[@"劳斯莱斯" , @"布加迪", @"兰博基尼"];        _array = @[c1, c3, c2];    }    return _array;}-(NSArray *)dataArray{    if (!_dataArray) {        //1.获取路径        NSString *path = [[NSBundle mainBundle] pathForResource:@"heros.plist" ofType:nil];                //2.加载数据        NSArray *array = [NSArray arrayWithContentsOfFile:path];                //3.模型转对象        NSMutableArray * mutableArray = [[NSMutableArray alloc]init];        for (NSDictionary *dict in array) {            GMLOL *data = [GMLOL lolWithDict:dict];                        [mutableArray addObject:data];        }        //4.赋值        _dataArray = mutableArray;    }    return _dataArray;}#pragma mark - 隐藏状态栏- (BOOL)prefersStatusBarHidden{    return YES;}#pragma mark - 计算字体/** *  根据文本获取文本占用的大小 * *  @param string  文本 *  @param font    字体 *  @param maxSize 最大的宽高 * *  @return  = */- (CGSize)sizeWithString:(NSString *)string font:(UIFont *)font maxSize:(CGSize)maxSize{    NSDictionary *dict = @{NSFontAttributeName:font};    //    Size:文本能占用的最大宽高    //    options: ios提供的计算方式    //    attributes: 字体和大小    //    context: nil    // 如果计算的文本超过了给定的最大的宽高,就返回最大宽高,如果没有超过,就返回真实占用的宽高    CGRect rect =  [string boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];    return rect.size;}@end

4.2展示

172818_TOXw_1032974.png       172819_dfue_1032974.png

转载于:https://my.oschina.net/wolx/blog/367311

你可能感兴趣的文章