iOS开发之计算动态cell的高度并缓存

FDTemplateLayoutCell的缓存机制
和FD*一样,我写了一个UITableView的category
在这个category里面又写了一个类,CellHeightCache
定义了三个方法

//是否已经缓存了
- (BOOL)existsHeightForKey:(id<NSCopying>)key {
    NSNumber *number = self.mutableCellHeightCaches[key];
    return number && ![number isEqualToNumber:@-1];
}
//缓存高度,传入key
- (void)cacheHeight:(CGFloat)height byKey:(id<NSCopying>)key {
    self.mutableCellHeightCaches[key] = @(height);
}
//传入key获得高度
- (CGFloat)heightForKey:(id<NSCopying>)key {
#if CGFLOAT_IS_DOUBLE
    return [self.mutableCellHeightCaches[key] doubleValue];
#else
    return [self.mutableCellHeightCaches[key] floatValue];
#endif
}

然后我在UITableView的分类里面写了两个方法

一个传入key获得高度,一个传入key和高度 缓存高度

- (CGFloat)getCellHeightCacheWithCacheKey:(NSString *)cacheKey
{
    if (!cacheKey) {
        return 0;
    }

    //如果已经存在cell height 则返回
    if ([self.cellHeightCache existsHeightForKey:cacheKey]) {
        CGFloat cachedHeight = [self.cellHeightCache heightForKey:cacheKey];
        return cachedHeight;
    } else {
        return 0;
    }
}

//缓存cell的高度
- (void)setCellHeightCacheWithCellHeight:(CGFloat)cellHeight CacheKey:(NSString *)cacheKey
{
    [self.cellHeightCache cacheHeight:cellHeight byKey:cacheKey];
}

他们都调用了这个方法

- (CellHeightCache *)cellHeightCache
{
    CellHeightCache *cache = objc_getAssociatedObject(self, _cmd);
    if (!cache) {
        cache = [CellHeightCache new];
        objc_setAssociatedObject(self, _cmd, cache, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return cache;
}

这两个方法用的是OC中runtime方法,原理是两个文件关联方法,和上层的存储方法> 差不多,传入value和key对应,取出也是根据key取出value
object传入self即可

1.设置关联方法

//传入object和key和value,policy
//policy即存储方式,和声明使用几种属性大致相同,有copy,retain,copy,retain_nonatomic,assign 五种)

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

2.取出方法

//传入object和key返回value
id objc_getAssociatedObject(id object, const void *key)

_cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例一样。
比如,我们要打印当前要调用的方法,可以这样来写:

 - (void)viewDidLoad{
    [super viewDidLoad];
    NSLog(@"Current method: %@ %@",[self class],NSStringFromSelector(_cmd));
    }
    输出结果如下:
    TestingProject[570:11303] Current method: stViewController viewDidLoad

这里是先获得缓存对象,如果为空的还就新创建一个,再进行关联。
这里用到了_cmd
_cmd是隐藏的参数,代表当前方法的selector,他和self一样都是每个方法调用时都会传入的参数,动态运行时会提及如何传的这两个参数。

经常和关联方法搭配一起用(Category 可以直接使用主类已有的私有成员变量,但不应该为实现 Category 而往主类中添加成员变量,考虑在 Category 的实现中使用 objc association 来达到相同效果。见http://blog.csdn.net/fscyj1/article/details/47829775

然后我在heightForRowAtIndexPath里面调用了

CGFloat cellHeight = [tableView getCellHeightCacheWithCacheKey:statusFrame.identifier];
NSLog(@"从缓存取出来的-----%f",cellHeight);

if(!cellHeight){
    statusFrame.status = status;
    cellHeight = statusFrame.cellHeight;
    [tableView setCellHeightCacheWithCellHeight:cellHeight CacheKey:statusFrame.identifier];
}

这样缓存高度就搞定了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值