iOS 的tabelView 重用机制 缓存池

本文介绍了iOS中UITableView的Cell重用机制,以解决因反复滚动导致的内存飙升问题。通过初始化时指定可重用标识,将Cell放入缓存池,在需要时从缓存池取出并更新内容。同时强调了`cellForRowAtIndexPath`方法的高效使用及不同类型的Cell如何设置多个可重用标识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UITableView中的单元格cell是在显示到用户可视区域后创建的,那么如果用户往下滚动就会继续创建显示在屏幕上的单元格,如果用户向上滚动返回到查看过的内容时同样会重新创建之前已经创建过的单元格。如此一来即使UITableView的内容不是太多,如果用户反复的上下滚动,内存也会瞬间飙升,更何况很多时候UITableView的内容是很多的(例如微博展示列表,基本向下滚动是没有底限的)。
 
在UITableView中也可以采用类似的方式,只是这时我们不是在滚动到指定位置后更改滚动的位置而是要将当前没有显示的Cell重新显示在将要显示的Cell的位置然后更新其内容。原因就是UITableView中的Cell结构布局可能是不同的,通过重新定位是不可取的,而是需要重用已经不再界面显示的已创建过的Cell。
 
当然,听起来这么做比较复杂,其实实现起来很简单,因为UITableView已经为我们实现了这种机制。在UITableView内部有一个缓存池,初始化时使用initWithStyle:(UITableViewCellStyle) reuseIdentifier:(NSString *)方法指定一个可重用标识,就可以将这个cell放到缓存池。然后在使用时使用指定的标识去缓存池中取得对应的cell然后修改cell内容即可。
 
上面的代码中已经打印了cell的地址,如果大家运行测试上下滚动UITableView会发现滚动时创建的cell地址是初始化时已经创建的。
 
这里再次给大家强调两点:
1. -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)方法调用很频繁,无论是初始化、上下滚动、刷新都会调用此方法,所有在这里执行的操作一定要注意性能;
2. 可重用标识可以有多个,如果在UITableView中有多类结构不同的Cell,可以通过这个标识进行缓存和重新。
 exp:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    //由于此方法调用十分频繁,cell的标示声明成静态变量有利于性能优化 
    static NSString *cellIdentifier=@"UITableViewCellIdentifierKey1"; 
    static NSString *cellIdentifierForFirstRow=@"UITableViewCellIdentifierKeyWithSwitch"; 
    //首先根据标示去缓存池取 
    UITableViewCell *cell; 
    if (indexPath.row==0) { 
        cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifierForFirstRow]; 
    }else{ 
        cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 
    } 
    //如果缓存池没有取到则重新创建并放到缓存池中 
    if(!cell){ 
        if (indexPath.row==0) { 
            cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierForFirstRow]; 
            UISwitch *sw=[[UISwitch alloc]init]; 
            [sw addTarget:self action:@selector(switchValueChange:) forControlEvents:UIControlEventValueChanged]; 
            cell.accessoryView=sw;
 
        }else{ 
            cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; 
            cell.accessoryType=UITableViewCellAccessoryDetailButton; 
        } 
    } 
     
    if(indexPath.row==0){ 
        ((UISwitch *)cell.accessoryView).tag=indexPath.section; 
    } 
     
    cell.textLabel.text=@"大爷的"; 
    cell.detailTextLabel.text=@"110"; 
    NSLog(@"cell:%@",cell); 
     
    return cell;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值