解析UITableViewCell的reuse问题
UITableView在iOS开发中会经常使用,对于行数很多的UITableView,可以通过UITableViewCell的重用,来保证执行效率。源码下载点击这里。
我们通过代码来探索UITableViewCell重用的实现,下面是一段使用UITableView的代码,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifier = @"myCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped reuseIdentifier:@"myCell"]; UITextField *tf; tf = [[UITextField alloc] initWithFrame:CGRectMake(100, 10, 150, 40) ]; tf.delegate = self; tf.borderStyle = UITextBorderStyleRoundedRect; [cell addSubview:tf]; [tf release]; cell.textLabel.text = [NSString stringWithFormat:@"%d",indexPath.row]; } // Configure the cell... return cell;}我们期待的是上下拖动UITableView,结果是这样
然而结果确实我们上下拖动后,都是
我们回到dequeueReusableCellWithIdentifier的定义
NSString *CellIdentifier = [NSString stringWithFormat:@"myCell_%d",indexPath.row];对于每一行,设定不同的reuseIdentifier。
CocoaTouch的开发人员也很与时俱进,在iOS6.0,终于有了新的方法
//ios 6.0 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"myCell"; [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; UITextField *tf; tf = [[UITextField alloc] initWithFrame:CGRectMake(100, 10, 150, 40) ]; tf.delegate = self; tf.borderStyle = UITextBorderStyleRoundedRect; [cell addSubview:tf]; [tf release]; cell.textLabel.text = [NSString stringWithFormat:@"%d",indexPath.row]; // Configure the cell... return cell; }我们先注册cell,然后再通过
- (id)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
//添加目标动作对,使其值改变时,自动保存至变量 [tf addTarget:self action:@selector(tfChange) forControlEvents:UIControlEventEditingDidEnd];