tableView简单认识以及性能优化
来源:互联网 发布:济南淘宝代运营公司 编辑:程序博客网 时间:2024/06/05 01:56
- 如何让tableView展示数据
- tableView的常见设置
- tableViewCell的常见设置
- tableView常见的代理方法
- cell的循环利用
- mutiSectionsTableView
- tableView如何展示数据
- 保持tableView数据独立
- 新需求再添加一组数据时候需要修改全部数据源方法
- 思路将所有需要修改的数据集中到一处
- 分析模型的创建
- 单组数据展示
- 缺少一张图片系统自带的cell样式
- tableView常见属性
- cell常见属性
- 常见代理易错属性
- 性能优化
- 思考cell进入屏幕创建离开屏幕销毁频繁调用极耗性能如何解决
- cell的循环利用
- 方法1传统方法
- 方法2注册
- 方法3storyboard
- sectionIndex索引条
- 复习多组数据的展示
- 复杂plist文件解析
- 宏定义
- 核心代码
- UITableViewController
- cellWithTableView
- cell获取封装
- 数据覆盖封装
- 封装后创建cell的数据源方法只需要3步
如何让tableView展示数据
- 设置数据源对象
/*也可以直接在storyboard中拖线,让tableView控件的delegate指 向ViewController*/self.tableView.dataSource = self;
- 数据源对象要遵守协议
@interface ViewController () <UITableViewDataSource>@end
- 实现数据源方法(向tableView中添加数据)
// 多少组数据- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;// 每一组有多少行数据- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;// 每一行显示什么内容- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;// 每一组的头部显示内容- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;// 每一组的尾部显示内容- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
tableView的常见设置
// 设置每一行cell的高度self.tableView.rowHeight = 100;// 设置每一组头部的高度self.tableView.sectionHeaderHeight = 50;// 设置每一组尾部的高度self.tableView.sectionFooterHeight = 50;// 设置分割线颜色self.tableView.separatorColor = [UIColor redColor];// 设置分割线样式self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;// 设置表头控件self.tableView.tableHeaderView = [[UISwitch alloc] init];// 设置表尾控件self.tableView.tableFooterView = [UIButton buttonWithType:UIButtonTypeContactAdd];// 设置右边索引文字的颜色self.tableView.sectionIndexColor = [UIColor redColor];// 设置右边索引文字的背景色self.tableView.sectionIndexBackgroundColor = [UIColor blackColor];
tableViewCell的常见设置
// 设置右边的指示样式(>形状图标,对勾图标,或者是Information图标)cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;// 设置右边的指示控件cell.accessoryView = [[UISwitch alloc] init];// 设置cell的选中样式cell.selectionStyle = UITableViewCellSelectionStyleNone;// backgroundView优先级 > backgroundColor// 设置背景色cell.backgroundColor = [UIColor redColor];// 设置背景viewUIView *bg = [[UIView alloc] init];bg.backgroundColor = [UIColor blueColor];cell.backgroundView = bg;// 设置选中的背景viewUIView *selectedBg = [[UIView alloc] init];selectedBg.backgroundColor = [UIColor purpleColor];cell.selectedBackgroundView = selectedBg;
tableView常见的代理方法
// 当点击cell的时候就会调用,选中当前的cell(cell选中样式为None的时候也会调用)- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath// 取消选中cell时调用的方法- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath// 返回对应的indexPath的cell的高度- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath// 返回第section组的组尾高度- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section// 返回第section组的组头高度- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section// 返回section的组尾view(优先级高于数据源方法)- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section// 返回section的组头view(优先级高于数据源方法)- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
cell的循环利用
- 传统的写法
/** * 每当有一个cell要进入视野范围内,就会调用一次 */- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *ID = @"wine"; // 1.先去缓存池中查找可循环利用的cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 2.如果缓存池中没有可循环利用的cell if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; } // 3.设置数据 cell.textLabel.text = [NSString stringWithFormat:@"%zd行的数据", indexPath.row]; return cell;}
- 新的写法(注册cell)-01
NSString *ID = @"wine";- (void)viewDidLoad { [super viewDidLoad]; // 注册某个重用标识 对应的 Cell类型 [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // 1.先去缓存池中查找可循环利用的cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 2.设置数据 cell.textLabel.text = [NSString stringWithFormat:@"%zd行的数据", indexPath.row]; return cell;}
- 新的写法(注册cell)-02
BOOL reged = NO;- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *ID = @"wine"; if (reged == NO) { // 注册某个重用标识 对应的 Cell类型 [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID]; reged = YES; } // 1.先去缓存池中查找可循环利用的cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 2.设置数据 cell.textLabel.text = [NSString stringWithFormat:@"%zd行的数据", indexPath.row]; return cell;}
- storyboard - 03
// 首先在storyboard中设置cell的identifier为@"wine",然后执行下面代码即可- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *ID = @"wine"; // 1.先去缓存池中查找可循环利用的cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 2.设置数据 cell.textLabel.text = [NSString stringWithFormat:@"%zd行的数据", indexPath.row]; return cell;}
mutiSectionsTableView
tableView如何展示数据?
- 通过数据源
@property (nonatomic, assign) id <UITableViewDataSource> dataSource;
设置数据源
// 1.在viewDidLoad方法中设置tableView.dataSource = self;// 2.在storyboard中拖线
- 遵守数据源协议
<UITableViewDataSource>
- 实现数据源方法
保持tableView数据独立
新需求再添加一组数据时候,需要修改全部数据源方法!
思路:将所有需要修改的数据集中到一处
- 创建一个新的数组属性
@property (nonatomic, strong) NSArray *groups; /**< group模型数组 */
- 通过懒加载为数组赋值
// 懒加载- (NSArray *)groups{ if (!_groups) { XMGGroup *g0 = [[XMGGroup alloc] init]; g0.header = @"adc"; g0.footer = @"物理输出脆皮"; g0.heros = @[[XMGHero heroWithName:@"艾希" Icon:@"hanbing"], [XMGHero heroWithName:@"崔斯特娜" Icon:@"xiaopao"], [XMGHero heroWithName:@"金克斯" Icon:@"金克斯"]]; XMGGroup *g1 = [[XMGGroup alloc] init]; g1.header = @"apc"; g1.footer = @"法术输出脆皮"; g1.heros = @[[XMGHero heroWithName:@"阿狸" Icon:@"ali"], [XMGHero heroWithName:@"火男" Icon:@"huonan"], [XMGHero heroWithName:@"球女" Icon:@"qiunv"]]; XMGGroup *g2 = [[XMGGroup alloc] init]; g2.header = @"上单"; g2.footer = @"上单爸爸不好惹"; g2.heros = @[[XMGHero heroWithName:@"大保健" Icon:@"dabaojian"], ]; _groups = @[g0, g1, g2]; } return _groups;}
这样再添加数据,只需要对懒加载中的数据进行操作即可
实际开发中,所用的数据也是从服务器拿到后展示出来的
分析模型的创建
- 组头
- 组尾
- cell上的内容(数组)
- 每个cell上的内容分为name和icon
- 创建hero模型
单组数据展示
- 数据源方法:返回多少组可以不实现
// Default is 1 if not implemented 如果不实现,默认就是1行//- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView//{// return 1;//}
- cell上自带3个展示信息的子控件
cell.textLabel.text = car.name; // 系统自带的cell的非value2样式并且有数据才展示 cell.imageView.image = [UIImage imageNamed:car.icon]; // 系统自带cell的非default样式并且有数据时候才展示 cell.detailTextLabel.text = car.money;
- 系统自带的cell的四个样式
缺少一张图片(系统自带的cell样式)
- 复习简单plist文件解析
// 1.拿到plist的文件路径 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"cars.plist" ofType:nil]; // 2.创建对应的JSON数据 NSArray *dicts = [NSArray arrayWithContentsOfFile:filePath]; // 3.JSON->Model NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:dicts.count]; for (NSDictionary *dict in dicts) { // 3.1 Dict->Model XMGCar *obj = [XMGCar carWithDict:dict]; [arrayM addObject:obj]; }
- Dict->Model
+ (instancetype)carWithDict:(NSDictionary *)dict{ XMGCar *car = [[self alloc] init];// car.name = dict[@"name"];// car.icon = dict[@"icon"];// car.money = dict[@"money"]; // kvc 相当于上面3行 [car setValuesForKeysWithDictionary:dict]; return car;}
tableView常见属性
// 设置tableView的属性- (void)setupTableViewProPerty{ // tableView的行高如果不修改,默认是44 self.tableView.rowHeight = 88; // 设置tableView组头,组尾的统一高度 self.tableView.sectionHeaderHeight = 44; self.tableView.sectionFooterHeight = 66; // 表头/尾 视图 self.tableView.tableHeaderView = [[UISwitch alloc] init]; self.tableView.tableFooterView = [UIButton buttonWithType:UIButtonTypeContactAdd]; // 分割线颜色 设置成[UIColor clearColor]代表去掉分割线 self.tableView.separatorColor = [UIColor redColor]; // 设置分割线样式 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;}
cell常见属性
#pragma mark - cell常见属性// 方法抽取的技巧就是将变量写成参数传进来// 相同业务逻辑的的代码尽量抽取成方法- (void)setupCellProperty:(UITableViewCell *)cell row:(NSInteger)row{ // cell的常见属性 // 设置cell的背景颜色 cell.backgroundColor = (row % 2)? [UIColor yellowColor]: [UIColor orangeColor]; // 设置cell的背景视图,并且backgroundView的优先级比backgroundColor高一些 // UIView *cellBg = [[UIView alloc] init]; // cellBg.backgroundColor = [UIColor grayColor]; // cell.backgroundView = cellBg; /* UITableViewCellAccessoryNone, // don't show any accessory view UITableViewCellAccessoryDisclosureIndicator, // 尖尖 regular chevron. doesn't track UITableViewCellAccessoryDetailDisclosureButton, // 圈i + 尖尖info button w/ chevron. tracks UITableViewCellAccessoryCheckmark, // 小对勾 checkmark. doesn't track UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0) // 圈i info button. tracks */ // cell的辅助视图样式 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; // cell的辅助视图,作用优先级高于accessoryType cell.accessoryView = [[UISwitch alloc] init]; /* UITableViewCellSelectionStyleNone, // 设置没有选中样式 UITableViewCellSelectionStyleBlue, // 在iOS6之前,选中背景色变蓝,iOS7之后,和gray相同 UITableViewCellSelectionStyleGray, // 默认样式 UITableViewCellSelectionStyleDefault NS_ENUM_AVAILABLE_IOS(7_0) // 默认样式 */ cell.selectionStyle = UITableViewCellSelectionStyleGray; // 在UITableViewCellSelectionStyleNone样式中,设置selectedBackgroundView是无效的 /* 在 UITableViewCellSelectionStyleBlue, // 在iOS6之前,选中背景色变蓝,iOS7之后,和gray相同 UITableViewCellSelectionStyleGray, // 默认样式 UITableViewCellSelectionStyleDefault NS_ENUM_AVAILABLE_IOS(7_0) // 默认样式 3种样式下,selectedBackgroundView他的优先级高于selectionStyle */ UIView *cellsBg = [[UIView alloc] init]; cellsBg.backgroundColor = [UIColor redColor]; cell.selectedBackgroundView = cellsBg; /* contentView = 0x7f96fb553470: cell.textLabel.superview = 0x7f96fb553470 ==0x7f96fb553470 ==0x7f96fb553470 */ // cell上面的子控件不是直接添加在cell上,而是添加到contentView上 NSLog(@"contentView = %p: cell.textLabel.superview = %p==%p==%p", cell.contentView, cell.textLabel.superview, cell.imageView.superview, cell.detailTextLabel.superview);}
注意:cell上面的子控件要添加到cell.contentView上
常见代理/易错属性
- 前两者易错
// 选中某一行时候调用- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSLog(@"%s, row = %ld", __FUNCTION__, indexPath.row);}// 取消选中某一行时候调用- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{ NSLog(@"%s, row = %ld", __FUNCTION__, indexPath.row);}// 根据indexPath返回对应的高度- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ if (indexPath.row == 0) { return 222; } return 88;}
- 分割线样式的枚举容易写错
#warning 在设置分割线样式为None的时候如果无效,先看你是否搞混了下列2个枚举 /* UITableViewCellSeparatorStyleNone UITableViewCellSelectionStyleNone */ self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
性能优化
思考:cell进入屏幕创建,离开屏幕销毁;频繁调用极耗性能如何解决?
- 利用
tableView的缓存池
,存放离开屏幕的cell - 当cell进入屏幕后,先取缓存池若没有再新建
- 这样就可以只创建
n+1
个cell来展示所有数据
–n表示屏幕上显示cell的最大数量
cell的循环利用
- 确定
重用标识
- 根据标识从
缓存池
中取- 封装若没有根据
注册
创建,拿到return,nil继续 - nil后继续查看
storyboard中
是否有带重用标识的cell
- 封装若没有根据
- 若返回nil则
手动创建
- 覆盖cell上的
数据
- 返回cell
方法1:传统方法
/* 0.先确定cell的重用标识 1.查看缓存池中是否有带重用标识的cell 2.如果没有才创建带重用标识的cell 3.覆盖cell上面的数据 说明:当cell离开屏幕的时候,就会放到tableView的缓存池中,这时候缓存池才有数据 */// 3.返回每行内容:// 该方法,只有当cell显示在屏幕上的时候才会调用,是一种懒加载的思想- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // 3.0 先确定cell的重用标识:命名规范:数据的模型+ID static NSString *ID = @"carID"; // static修饰局部变量,局部变量只会分配一次内存地址 // 3.1 查看缓存池中是否有带重用标识的cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 3.2 如果没有才创建带重用标识的cell if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; } // 3.3 覆盖cell上的数据 XMGCar *car = self.cars[indexPath.row]; cell.textLabel.text = [NSString... // 3.4返回cell return cell;}
方法2:注册
/* 另一中性能优化的写法: 0.先确定cell的重用标识 1.注册带重用标识的cell 2.从缓存池中取是否有带重用标识的cell(如果没有,系统会根据注册自动创建一个相应的cell返回给我们) 3.覆盖cell上面的数据 说明:当cell离开屏幕的时候,就会放到tableView的缓存池中,这时候缓存池才有数据 */// 3.返回每行内容:// 该方法,只有当cell显示在屏幕上的时候才会调用,是一种懒加载的思想- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // 3.0 先确定cell的重用标识:命名规范:数据的模型+ID static NSString *ID = @"carID"; // static修饰局部变量,局部变量只会分配一次内存地址 static BOOL isReged = NO; // 3.1 先注册带ID的cell if (isReged == NO) {#warning registerCell需要注意的3点,面试可能会问到 // 改方法是伴随着UICollectionView出现的,也就是iOS6出现的 // 采用注册创建出来的cell,默认是Default样式,所以一般注册大部分都用在自定义cell的时候 // 需要注意的是 [tableView registerNib:<#(UINib *)#> forCellReuseIdentifier:<#(NSString *)#>] 是iOS5出现的 [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID]; isReged = YES; NSLog(@"registerClassregisterClassregisterClassregisterClass"); } // 3.2 查看缓存池中是否有带重用标识的cell // 缓存池方法中封装了,如果缓存池中没有,就根据注册创建新的cell,然后返回给我们一个带ID的cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 3.3 覆盖cell上的数据 XMGCar *car = self.cars[indexPath.row]; cell.textLabel.text = [NSString... // 3.4返回cell return cell;}
方法3:storyboard
/* 另一中性能优化的写法(storyboard): 0.先确定cell的重用标识 1.将storyboard中的tableView中的cell的重用标志赋值 2.从缓存池中取是否有带重用标识的cell (2.1 如果没有,系统会根据注册自动创建一个相应的cell返回给我们; 2.2 如果也没有注册过,系统会根据storyboard中写好的带重用标志的cell来自动创建,然后返回) 3.覆盖cell上面的数据 说明:当cell离开屏幕的时候,就会放到tableView的缓存池中,这时候缓存池才有数据 */// 3.返回每行内容:// 该方法,只有当cell显示在屏幕上的时候才会调用,是一种懒加载的思想#warning 如果有注册,就不会触发storyboard的创建新cell的机制.只有没有注册过,并且storyboard中没有标记相应cell 的时候,dequeueReusableCellWithIdentifier才会返回nil- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // 3.0 先确定cell的重用标识:命名规范:数据的模型+ID static NSString *ID = @"carID"; // static修饰局部变量,局部变量只会分配一次内存地址 // 3.1 查看缓存池中是否有带重用标识的cell // 缓存池方法中封装了,如果缓存池中没有,就根据注册创建新的cell,然后返回给我们一个带ID的cell // 后面还封装了一层,如果也没有注册呢,会根据storyboard中是否标记了在重用cell,来创建一个新的cell然后返回 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 3.3 覆盖cell上的数据 XMGCar *car = self.cars[indexPath.row]; cell.textLabel.text = [N... // 3.4返回cell return cell;}
sectionIndex索引条
复习多组数据的展示
- 设置数据源
- 遵守协议(作用是方法提示)
- 实现数据源方法
复杂plist文件解析
- 见
字典
就转模型
(keys对应同名属性) - 层层递归
- KVC的实现
- 对应dictKeys的所有模型的属性set方法调用了一次
- 复杂类型转换放在属性的set方法中
宏定义
#define XMGDictToModel_H(name) + (instancetype)name##WithDict:(NSDictionary *)dict;#define XMGDictToModel_M(name)\+ (instancetype)name##WithDict:(NSDictionary *)dict\{\ NSObject *obj = [[self alloc] init];\ [obj setValuesForKeysWithDictionary:dict]; \ return obj; \}\#define dictToModel_H + (instancetype)modelWithDict:(NSDictionary *)dict;#define dictToModel_M \+ (instancetype)modelWithDict:(NSDictionary *)dict \{ \NSObject *obj = [[self alloc] init]; \[obj setValuesForKeysWithDictionary:dict]; \return obj; \} \
核心代码
// 索引条方法- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{// NSMutableArray *arrayM = [NSMutableArray array];// for (XMGCarGroup *carGroup in self.carGroups) {// [arrayM addObject:carGroup.header];// }// return [arrayM copy]; // 此处kvc效果 == 上面4行代码 return [self.carGroups valueForKeyPath:@"header"];}//补充// 设置索引条的背景/文字 颜色 self.tableView.sectionIndexBackgroundColor = [UIColor yellowColor]; self.tableView.sectionIndexColor = [UIColor redColor];
UITableViewController
- 继承在UIViewController
- 遵守数据源和代理协议
- 内部有个tableView
- 代码相当于如此
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 创建一个tableView UITableView *tableView = [[UITableView alloc] init]; // 设置数据源和协议 tableView.dataSource = self; tableView.delegate = self; // 替换view为tableView self.view = tableView;}
cellWithTableView:
cell获取封装
将获取cell的代码全部copy到cell内部,发现需要用到变量tableView,传入即可
传统封装
+ (instancetype)cellWithTableView:(UITableView *)tableView{ // 1.确定重用标识 static NSString *ID = @"carID"; // 2.从缓存池中取 XMGCarCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 3.如果缓存池中没有,就自己创建 if (!cell) { cell = [[XMGCarCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; } return cell;}
- 注册封装
+ (instancetype)cellWithTableView:(UITableView *)tableView{ // 1.确定重用标识 static NSString *ID = @"carID"; static BOOL isReged = NO; // 2.注册 if (isReged == NO) { [tableView registerClass:self forCellReuseIdentifier:ID]; isReged = YES; } // 3.从缓存池中取 XMGCarCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; return cell;}
数据覆盖封装
- 为cell添加模型属性
@property (nonatomic, strong) XMGCar *car; /**< carModel */
- 重写模型set方法完成内部赋值
- (void)setCar:(XMGCar *)car{ _car = car; self.imageView.image = car.icon; self.textLabel.text = car.name;}
封装后创建cell的数据源方法只需要3步
- 获取cell
- 覆盖数据
- 返回cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 3.1 获取cell XMGCarCell *cell = [XMGCarCell cellWithTableView:tableView]; // 3.2 数据覆盖 // 这样写的好处就是,将cell覆盖数据一行完成,具体覆盖了哪些数据,进入cell内部看 XMGGroup *g = self.groups[indexPath.section]; XMGCar *car = g.cars[indexPath.row]; cell.car = car; // 3.3.返回cell return cell;}
0 0
- tableView简单认识以及性能优化
- TableView 性能优化
- TableView 性能优化
- tableView cell性能优化
- tableView性能优化
- TableView性能优化
- TableView性能优化
- tableView 性能优化机制
- iOS性能优化-TableView
- TableView性能优化
- tableView性能优化
- tableview性能优化
- tableView的性能优化
- tableView的性能优化
- tableView性能优化
- iOS tableView性能优化
- iOS TableView性能优化
- 优化 scrollView 性能(tableView)
- 做人要有乐趣
- BLE_CC2540_初学者入门指导
- hiberante4连接oracle数据库入门
- 一个变量在uefi中的传递过程
- <HTML5>原生的强大DOM选择器querySelector
- tableView简单认识以及性能优化
- linq 调试转换成sql语句
- dataset中获取其中一个表中某列的值放到List中
- HDU 2112 HDU Today
- python logging 日志详细配置
- main(int argc, char * argv[])讲解
- MBR损坏修复(二)
- 关于memory warning
- MySQL单表百万数据记录分页性能优化