开源项目 FDTemplateLayoutCell研究
2016-02-22 17:50
330 查看
iOS泛型
可以指定容器中的对象类型,没有用任何的iOS runtime,纯编译器层面语法支持(llvm7.0,Xcode7以上),因此写好的程序可以在更低版本的iOS版本上愉快地跑起来。NSArray<NSString *> *strings = @[@"sun", @"yuan"]; NSDictionary<NSString *, NSNumber *> *mapping = @{@"a": @1, @"b": @2};
编译器支持的很好,代码提示也可以出来。strings[0].length毫无压力,编译通过。
定义一个泛型类
@interface Stack2<ObjectType> : NSObject - (void) push:(ObjectType)object; @end @implementation Stack2 - (void) push:(id)object { NSLog(@"Stack2!"); }
不指定泛型的类型可以可以和任意泛型类型转化,但是不同类型的泛型不可以强转。如Stack2< NSString*> 和 Stack2< NSMutableString*>
因此,就有了逆变和协变这个概念:
__covariant :子类型指针可以向父类型指针转换(有用,子类转基类)
__contravariant:父类型指针可以向子类型转换
但是更多地是使用 __kindof 修饰符,一个基类簇。UITableViewCell就是一个适用的例子。
define进阶技巧
define 参数加#,表示将数转成字符串,也就是加一对双引号 #define test1(a) NSLog(@#a); test1(frankpcl); 结果就是 NSLog(@"frankpcl") define 参数加##,表示将参数和其他字符粘合起来 #define test1(a) NSLog(@"%@",make_##a); NSString* make_frankpcl = @"pcl"; test1(frankpcl); 结果是 NSLog(@"%@",make_frankpcl) define可变参数,__VA_ARGS__ #define test1(a,...) NSLog(@#__VA_ARGS__); test1(aa,bb;cc,dd); 相当于 NSLog(@"bb;cc,dd") ##还有一个用处,当可变参数为空时,多出来的一个逗号可能会导致编译错误, #define test1(a,...) NSLog(@"aa",__VA_ARGS__); test1(aa); 会编译错误,因为最后转成 NSLog(@"aa",) 改成#define test1(a,...) NSLog(@"aa",##__VA_ARGS__); 会去掉多余的,从而编译成功
核心思想
cache,通过扩展的category UITableView (FDIndexPathHeightCache) 在heightForCell的时候,向用户要求cell的布局,计算出高度,并缓存,下次用户请求时,直接返回缓存值细节
既然有缓存就有清除机制,使用了一个category UITableView (FDIndexPathHeightCacheInvalidation) ,在+load方法调用时method swizzle了如下方法SEL selectors[] = { @selector(reloadData), @selector(insertSections:withRowAnimation:), @selector(deleteSections:withRowAnimation:), @selector(reloadSections:withRowAnimation:), @selector(moveSection:toSection:), @selector(insertRowsAtIndexPaths:withRowAnimation:), @selector(deleteRowsAtIndexPaths:withRowAnimation:), @selector(reloadRowsAtIndexPaths:withRowAnimation:), @selector(moveRowAtIndexPath:toIndexPath:) };
在这些实现中都需要全部或者部分的清空高度缓存
当device方向转动时,并没有清空缓存,而是用了两个列表的缓存分别表示横向和纵向的高度。
自动布局时,核心高度计算
fittingSize = [templateLayoutCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
手动布局时,需要用户实现下面函数来告知
- (CGSize)sizeThatFits:(CGSize)size
cache用联合存储方式来保存
objc_setAssociatedObject(self, _cmd, cache, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
相关文章推荐
- pow(x,n)
- JdbcTemplate使用别名绑定变量
- 大型分布式网站架构
- 死刑犯和CEO写给母亲的信,价值上亿!惊醒无数父母!
- linux访问windows共享文件夹的两种方法
- Leetcode Minimum Height Trees
- 取消tableviewcell选中效果
- 10位世界级投资大师100金句
- MySQL中TPS和QPS的计算方式
- 解决 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 问题
- Charles抓包使用教程
- css行级行内元素横向居中
- 寒假集训四之判断长方形问题 hdu5258 暴力枚举
- iOS中使用AVPLayer自定义视频播放器
- Android实现3D页面加载进度条动画
- ASP.NET应用程序与页面生命周期
- OnClick事件的Sender参数的前世今生——TWinControl.WinProc优先捕捉到鼠标消息,然后使用IsControlMouseMsg函数进行消息转发给图形子控件(意外发现OnClick是由WM_LBUTTONUP触发的)
- 分析cocos2d-x在Android上的编译过程(1):cocco2d-x是怎样生成的Android的文件夹结构
- 改动分区后,导致linux上不了
- angularjs中判断ng-repeat是否迭代完