【问题标题】:Prefilling the UICollectionView cell reuse queue预填充 UICollectionView 单元重用队列
【发布时间】:2014-03-19 15:06:00
【问题描述】:

问题

我有一个带有单个 UICollectionView 的应用程序,当我第一次滚动它时它会卡顿。我已将来源缩小到正在创建新单元 (2) 的事实(使用 initWithFrame:),因为周围没有可重复使用的单元。在初始滚动之后,重用队列不为空,并且可以重用单元格并且没有卡顿。

黑客攻击

所以我已经能够借助 iOS runtime headers 中的私有方法解决该问题:

- (void)_reuseCell:(id)arg1;

我的假设是,这是将单元格添加回重用队列的地方。使用这种未记录方法的 hack 如下所示:

int prefillCellCount = 10;
NSMutableArray *cells = [[NSMutableArray alloc] initWithCapacity:prefillCellCount];
for (int i=0; i<10prefillCellCount i++) {
    UICollectionViewCell *cell = [self.gridView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
    [cells addObject:cell];
}
for (UICollectionViewCell *cell in cells) {
    [self.gridView _reuseCell:cell];
}

破解有效!滚动时不会卡顿。

问题

我认为我无法通过这个 hack 获得 App Store 的审核。有没有办法在不使用未记录的方法的情况下做到这一点?如果没有,我唯一的办法就是混淆黑客吗?

【问题讨论】:

    标签: ios objective-c performance uicollectionview


    【解决方案1】:

    有没有办法在不使用未记录方法的情况下做到这一点?

    如果问题仅仅是创建单元格需要很长时间,那么您可以简单地创建一些附加项并在视图控制器中保留它们,直到集合要求它们为止。像您在代码中所做的那样预先分配一些单元格,调用dequeueReusableCellWithReuseIdentifier: 以获取集合来为您创建它们。将这些保存在视图控制器的数组中。接下来,在您的 ...cellForItemAtIndexPath: 方法中,如果数组不为空,请从数组中删除一个单元格并使用它,而不是向集合视图询问可重用单元格。

    这应该可以通过移动创建单元格的点而不使用任何未记录的方法来解决您的问题。

    另一种方法是加快单元创建过程,这样您就不必费心预先分配单元。分析您的代码以了解为什么您的单元格需要这么长时间才能构建。也许您可以通过删除不必要的视图来简化您的单元格结构?

    【讨论】:

    • 谢谢,这个解决方案效果很好。只需确保预分配的单元格与正在显示的单元格具有相同的索引路径即可。
    • @scompt.com 这仍然对你们有用吗?当我在 iPad 3 上尝试这个时,我得到的视图到处都消失了(诚然,dequeue 方法确实存在已知问题:stackoverflow.com/questions/19276509/…)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多