UITableViewCell对父级UITableView的引用?

7 浏览
0 Comments

UITableViewCell对父级UITableView的引用?

UITableViewCell内部是否有办法访问所属的UITableView

0
0 Comments

问题:如何从UITableViewCell中引用到其父UITableView?

原因:在iOS中,UITableViewCell是UITableView的子组件,但是没有提供直接获取父UITableView的属性或方法。因此,需要通过遍历视图层次结构来查找包含该单元格的表格视图。

解决方法:可以使用以下类别来实现获取父UITableView的方法。这种方法不依赖于任何特定的UITableView层次结构,适用于任何iOS版本,只要UITableView类名不改变。通过导入该类别,并使用[myCell parentTableView]方法来获取引用。

UIView (FindUITableView)
-(UITableView *) parentTableView {
    // iterate up the view hierarchy to find the table containing this cell/view
    UIView *aView = self.superview;
    while(aView != nil) {
        if([aView isKindOfClass:[UITableView class]]) {
            return (UITableView *)aView;
        }
        aView = aView.superview;
    }
    return nil; // this view is not within a tableView
}

使用方法:

UITableView *myTable = [myTableCell parentTableView];
UITableView *myTable = [myCellLabel parentTableView];

需要注意的是,如果在尚未添加到UITableView中的单元格上调用该方法,将返回nil。因此,应该在已经添加到UITableView的单元格或子视图上调用该方法。

更新:有关是否使用弱引用的讨论。这取决于具体情况。遍历视图层次结构会带来一些小的运行时开销,因为需要循环直到找到目标UIView。如果视图层次结构很深,这个开销就会更大。另一方面,在每个单元格上保留引用只会带来很小的内存开销(弱引用本质上是一个指针),并且通常在不需要的地方添加对象关系是一种不好的面向对象设计实践,应该避免。而且,将表格引用保存在单元格内部会增加代码复杂性,并且可能导致错误,因为UITableViewCell是可重用的。因此,使用类别来实现获取父UITableView的方法在单个单元格与表格交互时(例如,用户与单元格交互时)的运行时成本应该是微不足道的。

如果你发现自己需要遍历子视图,应该问问自己为什么需要这样做。这个坏主意在iOS 7中的UITableViewCell的更改中得到了很好的说明,这将导致该方法始终返回nil。如果你需要从单元格获取UITableView,弱引用是更好的选择。

因此,将UITableView的引用保存在UITableViewCell中会增加代码复杂性,并且可能导致内存泄漏(即,单元格的生命周期超过表格的生命周期)。UIKit没有提供cell.parentTable属性,这并不是巧合。

结论:根据良好的面向对象设计原则(如迪米特法则),将对子视图的引用保存在UITableViewCell中是不推荐的。遍历视图层次结构来查找父UITableView是一种更好的解决方案,可以在任何iOS版本中使用。

0
0 Comments

问题的原因是在UITableViewCell中需要引用其所在的UITableView,以便于在需要的时候与其进行交互。然而,直接使用self.superview来获取UITableView可能不稳定,因为UITableView的视图层次可能在未来发生变化。因此,需要采用一种更可靠的方法来获取UITableView。

解决方法是在UITableViewCell中存储一个weak引用指向其所在的UITableView。这个引用应该在UITableView的dataSource的tableView:cellForRowAtIndexPath:方法中进行设置。这种方法比依赖self.superview来获取UITableView更可靠。为了安全起见,还可以添加一个[self.superview isKindOfClass:[UITableView class]]的检查,以防将来视图层次发生变化。

另外,还可以使用一个Category来遍历子视图,而不依赖于特定的视图层次结构。这种方法可以保证在将来的版本中也能正常工作。这样就不需要在代码中到处散布引用,增加对象之间的耦合度。

某些情况下将UITableView的引用存储在UITableViewCell中会引入紧耦合和违反面向对象设计的迪米特法则。然而,苹果并没有提供一个"parentTable"属性,也没有明确说明他们的动机。在许多情况下,不需要引用表格,因此添加引用会消耗内存。而且,添加引用可能会导致问题,因为人们往往会在单元格中引用表格。当单元格被重用时,配置单元格可能无意中对表格进行调用。因此,更好的方法是使用一个弱引用,使用一点内存来替代不断遍历视图层次结构,从而节省电池的消耗。

总之,为了在UITableViewCell中引用其所在的UITableView,应该在UITableViewCell中存储一个weak引用指向其所在的UITableView,而不是依赖于self.superview。这样可以保证在任何版本中都能正常工作,并避免耦合和不必要的性能损耗。

0
0 Comments

问题的原因是在tableView的cellForRowAtIndexPath方法中,给每个cell的updateCallback属性赋值时,只给了一个cell的updateCallback赋值,没有给另一个cell的updateCallback2赋值,导致updateCallback2为nil。

解决方法是在tableView的cellForRowAtIndexPath方法中给每个cell的updateCallback2属性赋值,例如:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell: ItemCell = self.ItemTableView.dequeueReusableCellWithIdentifier("ItemCell") as! ItemCell!

cell.updateCallback = UpdateCallback //add this extra line

cell.updateCallback2 = UpdateCallback2 //add this line to assign value to updateCallback2

cell.lblItemDescription?.text = self.SomeList[indexPath.row].Description

return cell

}

这样就能保证每个cell的updateCallback和updateCallback2都有值了。

0