如何重用/回收像uitableviewcell这样的自定义元素呢?

时间:2011-02-06 16:10:17

标签: iphone objective-c uiscrollview reusability

使用UITableView时,我们可以使用[[ UITableViewCell alloc] initWithStyle: reuseIdentifier:][uiTableViewInstance dequeueReusableCellWithIdentifier:]方法重用其单元格。这有助于保持内存检查大型表格,因为在给定时刻视图中只有少数单元格。

我想创建一个包含许多子视图的UIScrollView。插入所有子视图占用了我想要避免的大量内存和初始时间。 Apple API是否提供了重用这些自定义组件(UIView或其子类)的方法,就像使用标识符的单元格视图一样?

如果没有API,我会创建一个,但对此有一些疑问。例如,对于每个新的子视图,我在previos视图之后设置其帧位置。如何在回收时更新每个子视图的框架?我应该删除并重新加载每个子视图的内容,因为它被回收了吗?我应该在另一个线程中进行所有这些计算以避免不稳定的滚动吗?总之,我希望在UITableView中有一个平滑的滚动体验,包括所有重复使用的东西。

以下是我到目前为止编写的代码示例:

int numberOfPages = 0;
int pageWidth = 100;
int pageHeight = 100

UIScrollView *myScrollView = //allocate and initialize a scrollview
//set its size to 100 by 100 (width equal to pageWidth)
//set paging enabled for myScrollView

从方法中添加子视图,多次调用

- (void) appendSubViewToScrollView {
    UIView *view = //allocate and initialize a view and dump data in it.

    CGRect rect = view.frame;
    rect.size.height = pageHeight;
    rect.size.width = pageWidth;
    rect.origin = CGPointMake(pageHeight * numberOfPages, 0);
    view.frame = rect;

    [myScrollView addSubview:view];

    numberOfPages++;

    [scrollView setContentSize:CGSizeMake(pageHeight * numberOfPages, pageWidth)];

    [view release];
}

编辑:
对tableview及其单元格如何在幕后实现这一点的一些见解将是有用的。

1 个答案:

答案 0 :(得分:19)

是的,您应该每次都恢复每个子视图内容,就像在表格视图中一样。回收子视图的优势在于节省了视图存储空间,节省了视图分配时间,但当然内容数据管理由您决定。

因此,标准回收方法要求您使用多个单元格,这些单元格等于屏幕上同时可见的视图数量+开始滚动时可能获得的额外单元格数量。 比方说,例如,您一次显示5个完整视图(滚动视图稳定),然后滚动时您将需要一个额外的视图,部分显示,所以最后您需要5 + 1 = 6个视图。理论上,建议使用2个以上的视图。 因此,您需要编写两个池:一个名为“visibleViews”,它由作为子视图添加到scrollview的所有视图组成,另一个名为“availableViews”,由可用于重复使用的所有视图组成。 然后创建所有这些视图并将它们添加到滚动视图(是的:您需要根据它们在scrollview中的位置调整它们的帧,是的,您需要再次设置内容)。 最后,您需要通过设置委托来跟踪滚动视图移动。此跟踪的目的是计算哪些可见视图不再可见,然后将其从可见池中删除并移至可用池。除了委托必须了解新单元格何时出现但仍然不可见,然后从可用池中获取它(如果池为空则为alloc / init)并添加到可见池和子视图中滚动视图。 当然,如果你想提高性能,你可以在滚动视图中放置更多的子视图,以避免在它们开始出现在屏幕上时精确移动单元格,这就是为什么我建议在滚动视图的两侧使用一些额外的视图

WWDC 2010中有一个很棒的视频(如果您是注册开发人员,可以访问它)关于iOS中滚动视图的使用:它解释了这种技术。

Apple的PhotoScroller XCode文档中的示例代码基本上完成了WWDC视频中所述的内容并解释了这种技术。