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对象

iOS中UITableView的一些问题思考的更多相关文章

  1. iOS中UITableView的cell点击事件不触发didSelectRowAtIndexPath(汇总)

    iOS中UITableView的cell点击事件不触发didSelectRowAtIndexPath 首先分析有几种原因,以及相应的解决方法 1.UITableViewCell的userInterac ...

  2. iOS中UITableView分割线左侧顶齐

    iOS 7开始UITableView的分割线不在从左侧边界开始了,而是默认空出了一段距离. 如果想要使用默认的分割线而且还要从左侧边界开始的话,有几种解决方式: 1.在tableView的代理方法中设 ...

  3. iOS中UITableView的一些设置

    不可滑动: ? 1 tableView.userInteractionEnabled = NO; 也可以在storyboard中的userInteractionEnable属性设置 显示导向箭头: ? ...

  4. iOS中UITableView数据源刷新了,但tableview当中的cell没有刷新

    你会不会遇到通过断点查看数据源模型的确刷新了,但是tableview没有刷新的情况,我遇到了,并通过下面的方法解决了,供大家参考! 在tableview中的数据源代理方法 p.p1 { margin: ...

  5. iOS中UITableView和UICollectionView的默认空态页

    项目中想实现空态页风格统一控制的效果,就封装了一个默认空态页,使用的技术点有:1 方法替换 ,2 给分类(Category)添加属性. 我们知道,扩展(extension)可以给类添加私有变量和方法. ...

  6. ios中uitableview上拉刷新和下拉刷新(1)

    在一个项目开发过程中为了更好的体验经常会用到下拉刷新更新数据,当然也伴随一些上拉加载更多数据的情况:当前比较火的EGOTableViewPullRefresh只实现了下拉功能,而没有上拉的功能.这里介 ...

  7. IOS中UITableView异步加载图片的实现

    本文转载至 http://blog.csdn.net/enuola/article/details/8639404  最近做一个项目,需要用到UITableView异步加载图片的例子,看到网上有一个E ...

  8. iOS 中UITableView的深理解

    例如下图:首先分析一下需求:1.根据模型的不同状态显示不同高度的cell,和cell的UI界面. 2.点击cell的取消按钮时,对应的cell首先要把取消按钮隐藏掉,然后改变cell的高度. 根据需求 ...

  9. IOS中UITableview中封装九宫格

    第一步引入SecondNav目录即可 第二步引入头文件 #import "DIYTableView.h" #import "invoiceInfo.h" 实现协 ...

随机推荐

  1. xml解析、写入遇到的坑

    前言 最近在看一个线上xml文件导出的问题,需求如下: 从我们平台导出一个后缀为tmx的术语语料数据(实际内容为xml文件),然后导入到其他第三方平台发现无法导入. 从其他平台导入的tmx文件无法导入 ...

  2. Spring与线程安全

    Spring作为一个IOC/DI容器,帮助我们管理了许许多多的“bean”.但其实,Spring并没有保证这些对象的线程安全,需要由开发者自己编写解决线程安全问题的代码. Spring对每个bean提 ...

  3. linux每日命令(35):grep命令

    Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局正则表达 ...

  4. idea配置项目运行时内存大小

    选择 edit Configurations : -server -XX:PermSize=1024M -XX:MaxPermSize=2048M

  5. lua系列之 lua-cjson模块安装报错问题解决

    lua-cjson下载 下载地址 报错信息 [root@LeoDevops lua-cjson]# make cc -c -O3 -Wall -pedantic -DNDEBUG -I/usr/loc ...

  6. golang模板语法

    https://www.cnblogs.com/Pynix/p/4154630.html https://blog.csdn.net/huwh_/article/details/77140664 ht ...

  7. 07装饰模式Decorator

    一.什么是装饰模式 装饰( Decorator )模式又叫做包装模式.通 过一种对客户端透明的方式来扩展对象的功能, 是继承关系的一个替换方案. 二.装饰模式的结构 三.装饰模式的角色和职责 抽象组件 ...

  8. 面试题思考:GET和POST两种基本请求方法的区别

    面试回答: GET请求在URL中传送的参数是有长度限制的,而POST没有. GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息. GET参数通过URL传递,POST放在Re ...

  9. Linux设备驱动剖析之Input(一)

    前言 以前在移植Qt到开发板上时只知道在配置文件中需要指定触摸屏的设备文件/dev/input/event0,仅此而已.直到一年半前突然想到用红外遥控器控制Tiny6410开发板上的Android系统 ...

  10. Ubuntu下SSH无密码验证配置

    前言 SSH为Secure Shell 的缩写,是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议.越来越多的小伙伴们使用远程登录,而ssh安全性无疑是很高的,那么我们现在来看看如何实现ss ...