iOS中UITableView的一些问题思考

UITableview的数据源为什么是代理,而不是引用?

我的理解,一般情况下控制器会引用tableView, 数据源和代理方法都是tableView的一个若引用,出了“tableView.datasource = slef;”这句代码的作用域。tableView.dataSource 就是nil了。如果不是代理而是引用的话,tableView被控制器引用,tableView.datasource有指向控制器,就是一个循环引用了。

关于tableView的数据源和代理的补充:

dataSource 是UITableViewDataSource类型,主要为UITableView提 供显示用的数据(UITableViewCell),指定UITableViewCell支持的编辑操作类型(insert,delete和 reordering),并根据用户的操作进行相应的数据更新操作,如果数据没有更具操作进行正确的更新,可能会导致显示异常,甚至crush。

delegate 是UITableViewDelegate类型,主要提供一些可选的方法,用来控制tableView的选择、指定section的头和尾的显示以及协助完成cell的删除和排序等功能。

UITableView声明了一个NSIndexPath的类别,主要用 来标识当前cell的在tableView中的位置,该类别有section和row两个属性,前者标识当前cell处于第几个section中,后者代 表在该section中的第几行。

  UITableView只能有一列数据(cell),且只支持纵向滑动,当创建好的tablView第一次显示的时候,我们需要调用其reloadData方法,强制刷新一次,从而使tableView的数据更新到最新状态。

初始化加载时代理和数据源方法的调用顺序:

#pragma mark - Table view data source
//section个数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; #pragma mark - Table view delegate
//headerView的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section; #pragma mark - Table view data source
//某个section里cell的个数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; #pragma mark - Table view delegate
//cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;#pragma mark - Table view data source
//cell 对象
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; #pragma mark - Table view delegate
//headerView
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;

tableVie滚动加载时调用的方法

#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
#pragma mark - Table view delegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

cell 重用机制:

重用原理:当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回UITableViewCell时,dataSource会先查看这个对象池,如果池中有未使用的UITableViewCell,dataSource会用新的数据配置这个UITableViewCell,然后返回给UITableView,重新显示到窗口中,从而避免创建新对象

还有一个非常重要的问题:有时候需要自定义UITableViewCell(用一个子类继承UITableViewCell),而且每一行用的不一定是同一种UITableViewCell(如短信聊天布局),所以一个UITableView可能拥有不同类型的UITableViewCell,对象池中也会有很多不同类型的UITableViewCell,那么UITableView在重用UITableViewCell时可能会得到错误类型的UITableViewCell

解决方案:UITableViewCell有个NSString *reuseIdentifier属性,可以在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(一般用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先通过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,如果有,就重用,如果没有,就传入这个字符串标识来初始化一个UITableViewCell对象

上一篇:扫描工具Nikto-安全牛课堂网络安全之Web渗透测试练习记录


下一篇:好好写代码吧,没事别瞎B去创业!