IOS UITableView详解二性能优化 & LOL游戏人物展示

一 重用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 ()<UITableViewDataSource,UITableViewDelegate>
/**
 *  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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值