tableView循环引用以及缓存池中的两个常见Bug

一、直接看Bug:unable to dequeue a cell with identifier cell_id - must register a nib or a class for the identifier or connect a prototype cell in a storyboard

二、使用tableView的cell重用机制后cell中不显示detailTextLabel。

*

*  本文中大量涉及tableView的重新引用机制

*  在tableView上下滑动的时候会自动销毁不在屏幕显示的tableViewCell,并且同时创建新的tableViewCell来加载新的数据,在创建一个新的cell和销毁一个滑出屏幕的cell时,会消耗手机中大量的内存资源,所以苹果公司在6.0发布后引用了一个新的方法,dequeue reusable!方法名称的意思为:可以重新引用的,源文件代码如下:

*   - (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); // newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered

*  在cell被新建的时候,使用次方法系统会自动在“缓存池”中寻找匹配,寻找匹配的两个要求,1.唯一标识ID相同,2.cell类型相同

*  在cell滑出屏幕的时候,cell会被系统自动放入缓存池中,并且绑定唯一标示ID,类型在创建的时候被声明。

*  在工具栏中的唯一标识如下图

*  Bug就出现在这个地方:

*  unable to dequeue a cell with identifier cell_id - must register a nib or a class for the identifier or connect a prototype cell in a storyboard

*  这句话的意思为系统找缓存池中寻找带有相同唯一标识的ID但是类型不明确,或者没有找到相同类型的xib。

*  由于寻找匹配重新引用“缓存池”中的cell要满足两个条件:唯一标识ID和唯一标识ID对应的类型也要相同,但是苹果提供的次方法只能确定唯一标识,所以要在程序启动的时候viewDidLoad中告诉系统在“缓存池”中寻找cell时候唯一ID对应的类型。

*  解决bug的方法:

*  给tableView注册一个cell,并且告诉系统cell的类型样式

*  在viewDidLoad中声明的代码如下:

*    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];

*  2.第二个小问题

*  使用tableView的cell重用机制后cell中不显示detailTextLabel。

*  如果用UITableViewCell的类创建一个cell,系统默认的cell的样式为UITableViewCellStyleDefault,这种样式不会显示detaiTextLabel,所以要重新构建一个类,重写init方法设置cell的格式为UITableViewCellStyleSubtitle

*  用自己写的一个类创建的cell的样式为UITableViewCellStyleSubtitle,可以显示detaiTextLabel

*    [self.tableView registerClass:[ERTableViewCell class] forCellReuseIdentifier:ID];

*  如果用到了其他样式的cell,可以自定义一个继承于UITableViewCell的类,并且重写init的方法,使其初始化的时候改变系统的默认样式

*  苹果提供了cell的四种类型:UITableViewCellStyleDefault(系统默认样式)、UITableViewCellStyleValue1、UITableViewCellStyleValue2、UITableViewCellStyleSubtitle

*  源文件如下

*      UITableViewCellStyleDefault, // Simple cell with text label and optional image view (behavior of UITableViewCell in iPhoneOS 2.x)

UITableViewCellStyleValue1, // Left aligned label on left and right aligned label on right with blue text (Used in Settings)

UITableViewCellStyleValue2, // Right aligned label on left with blue text and left aligned label on right (Used in Phone/Contacts)

UITableViewCellStyleSubtitle // Left aligned label on top and left aligned label on bottom with gray text (Used in iPod).

*  小小案例还有两个值得注意的点:

*  1.

//用static修饰ID是让ID一直保存在静态区域,当不引用的时候ID也不会被销毁,保证了唯一标识ID在程序运行时候的ID的地址和值的稳定性

//而@"cell_id"是保存在堆区的

static NSString * ID = @"cell_id";

2.

//用__weak修饰weakAlertCountroller是为了在下文中经过block引用后copy变成强引用,避免循环引用,在开发中block引用外部的对象时通常创建一个被__weak修饰的临时对象,在block中调用临时对象

__weak typeof(alertCountroller) weakAlertCountroller = alertCountroller;

源代码传送门:http://pan.baidu.com/s/1gexiydl

*/

时间: 2024-10-06 16:22:24

tableView循环引用以及缓存池中的两个常见Bug的相关文章

Kubernetes中,两种常见类型的Volume深度实践

一.背景 存储资源在所有计算资源中扮演着十分重要的角色,大部分业务场景下都有可能使用到各类存储资源.在Kubernetes中,系统通过Volume对集群中的容器动态或静态提供存储资源.通常情况下,我们可以认为容器或者Pod的生命周期时短暂的,当容器被销毁时,容器内部的数据也同时被清除.为了持久化保存容器的数据,Kubernetes引入了Volume,类似于Docker的Volume(Docker also has a concept of volumes, though it is somewh

iOS开发:一个瀑布流的设计与实现(已实现缓存池功能,该功能使得瀑布流cell可以循环利用)

一个瀑布流的实现有三种方式: 继承自UIScrollView,仿写UITableView的dataSource和delegate,创造一个缓存池用来实现循环利用cell 写多个UITableview(UITableView的cell宽度是与UITableView宽度一样的,那么每行可以摆设多个宽度相等的UITableView,从而实现瀑布流),不过这种方法是最差的,因为不能有效的做到循环利用cell 可以自定义UICollectionViewCell的布局,从而实现瀑布流,UICollectio

【iOS开发-68】APP下载案例:利用tableView自带的cell布局+缓存池cell复用时注意按钮状态的检查

(1)效果 (2)源代码与资源下载 http://pan.baidu.com/s/1pJLo2PP (3)总结 --核心是利用UITableView里面自带的cell来制作样式相同的cell. 与之相应的是,因为不是整个xib文件,所以加载这个cell时有一些区别,只需要在缓存池中取即可(利用ID). +(instancetype)cellWithTableView:(UITableView *)tableView{ static NSString *[email protected]"app&

EntityFramework中Json序列化的循环引用问题解决--Newtonsoft.Json

1.在使用EF时,由于数据库主外键关联,将对象进行Json序列化时会遇到循环引用的问题 //EF 中由于数据库主外键关联,对象的序列化经常出现循环引用问题 //使用.Net 自带的序列化工具,序列化出现循环引用问题 List<student> list = _Context.students.ToList(); JavaScriptSerializer ser = new JavaScriptSerializer(); string str = ser.Serialize(list); Con

简单聊一聊JS中的循环引用及问题

本文主要从 JS 中为什么会出现循环引用,垃圾回收策略中引用计数为什么有很大的问题,以及循环引用时的对象在使用 JSON.stringify 时为什么会报错,怎样解决这个问题简单谈谈自己的一些理解. 1. 什么是循环引用 当对象 1 中的某个属性指向对象 2,对象 2 中的某个属性指向对象 1 就会出现循环引用,(当然不止这一种情况,不过原理是一样的)下面通过代码和内存示意图来说明一下. function circularReference() { let obj1 = { }; let obj

tableView循环利用性能优化

tableView性能优化 - cell的循环利用方式1 /** * 什么时候调用:每当有一个cell进入视野范围内就会调用 */ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 0.重用标识 // 被static修饰的局部变量:只会初始化一次,在整个程序运行过程中,只有一份内存 static NSString *ID = @"c

Spring 循环引用 ——理解singleton与prototype初始化的区别

所谓的循环引用,就是A依赖B,B又依赖A,A与B两个对象相互持有.像下面这种情况: class A { B b; public A(B b) { this.b=b; } } class B { A a; public B(A a ) { this.a=a; } } 我们知道spring在获取对象或者在加载的时候,触发依赖注入.例如触发A对象的依赖注入,发现需要B对象,而此时B还没有初始化,就去实例化B对象,而又需要A对象,这样就进入了一种死循环状态,有点像操作系统里面的死锁.似乎这种情况发生了,

Spring 循环引用(二)源码分析

Spring 循环引用(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) Spring 循环引用相关文章: <Spring 循环引用(一)一个循环依赖引发的 BUG>:https://www.cnblogs.com/binarylei/p/10325698.html <Spring 循环引用(二)源码分析>:https://www.cnblogs.com/binarylei/p/1032604

《Java架构筑基》从Java基础讲起——基础类型缓存池概念

以Integer为例 new Integer(123) 与 Integer.valueOf(123) 的区别在于: new Integer(123) 每次都会新建一个对象: Integer.valueOf(123) 会使用缓存池中的对象,多次调用会取得同一个对象的引用. Integer x = new Integer(123); Integer y = new Integer(123); System.out.println(x == y); // false Integer z = Integ