将数据从UITableViewCell传递到UITableViewController的配方

我正在找出将数据从UITableViewCell传递到UIableViewController (或UIViewController )的正确机制。

在stackoverflow中搜索我找到了不同的方法来做到这一点,最后我找到了一个运行良好的机制,但我不知道它是否是一个有效的方法。

这就是场景。 首先,我创建了一个名为DataTableViewCell的自定义单元(与xib接口相关联),它扩展了UITableViewCell 。 这个单元格有一些显示(和修改)数据的出口和一个名为index的成瘾属性,如下所示:

 @property (nonatomic, copy) NSIndexPath* index; 

UITableViewController的方法cellForRowAtIndexPath方法内刷新此属性:

 - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath { DataTableViewCell *cell = (DataTableViewCell*)[tv dequeueReusableCellWithIdentifier:kCellTableIdentifier]; if (cell == nil) { [[NSBundle mainBundle] loadNibNamed:@"DataTableViewCell" owner:self options:nil]; cell = (DataTableViewCell*)self.dataTableViewCellOutlet; } // configure the cell with data // do stuff here... // configure the cell with the current indexPath cell.index = indexPath; return cell; } 

由于可以更改单元格中的值,因此我需要将数据传递给UITableViewController以更新模型。 为此,我决定使用委托机制。 所以,我使用如下方法创建了一个协议:

 - (void)updateData:(DataItem*)dataItem atIndexPath:(NSIndexPath*)index; 

UITableViewController实现该协议。 通过这种方式,在单元格内(针对某些事件),我可以调用该方法并以正确的方式更新模型。

说完这个,我有一些问题要问:

  1. 这是将数据从单元格传递到控制器的正确机制吗?
  2. 使用像单元格中使用的索引属性一样正确吗?
  3. 使用保留策略而不是复制策略是否相同。 可能有什么区别?
  4. 由于我发现的解决方案可能非常有计划,是否可以使用块代替?

关于街区,我这样想:

在单元格内创建一个属性块,如下所示:

 @property (nonatomic, copy) void (^updateModelOnEvent)(DataItem* dataItem); 

然后在UITableViewController的方法cellForRowAtIndexPath方法内部将该属性分配给这样的块代码(此代码与cell.index = indexPath;处于同一级别cell.index = indexPath; ):

 // configure the cell with the current indexPath cell.updateModelOnEvent = ^(DataItem* dataItem) { [self.model insertObject:dataItem atIndex:indexPath.row]; }; 

可能是一个有效的选择? 在这种情况下,我是否必须使用复制或保留策略?

先谢谢你。

为什么不直接使用[UITableView indexPathForCell:]与委托?

MyViewController.h

 @interface MyViewController : UITableViewController  @end 

MyViewController.m

 @implementation MyViewController // methods... - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *reuseIdentifier = @"MyCell"; MyTableViewCell *cell = (id)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; if (cell == nil) cell = [[[MyTableViewCell alloc] initWithMyArgument:someArgument reuseIdentifier:reuseIdentifier] autorelease]; [cell setDelegate:self]; // update the cell with your data return cell; } - (void)myDelegateMethodWithCell:(MyTableViewCell *)cell { NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; // update model } @end 

MyTableViewCell.h

 @protocol MyTableViewCellDelegate; @interface MyTableViewCell : UITableViewCell @property (assign, nonatomic) id  delegate; - (id)initWithMyArgument:(id)someArgument reuseIdentifier:(NSString *)reuseIdentifier; @end @protocol MyTableViewCellDelegate  @optional - (void)myDelegateMethodWithCell:(MyTableViewCell *)cell; @end 

MyTableViewCell.m

 @implementation MyTableViewCell @synthesize delegate = _delegate; - (id)initWithMyArgument:(id)someArgument reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; if (self) { // custom setup } return self; } - (void)prepareForReuse { [super prepareForReuse]; self.delegate = nil; } - (void)someActionHappened { if ([self.delegate respondsToSelector:@selector(myDelegateMethodWithCell:)]) [self.delegate myDelegateMethodWithCell:self]; } @end 
  1. 要修改单元格,您应该修改数据模型并重新加载表格数据。 没有其他的。
  2. 没有必要为cell提供indexPath
  3. 在您的情况下,使用保留或复制策略是相同的。 复制使新对象具有相同的状态。