预填充UICollectionView单元重用队列

时间:2021-04-05 04:07:29

The Problem

问题

I have an app with a single UICollectionView that's stuttering the first time that I scroll it. I've narrowed the source down to the fact that new cells (2) are being created (using initWithFrame:) because there are no cells lying around to be reused. After that initial scroll, the reuse queue isn't empty and cells can be reused and there's no stuttering.

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

The Hack

哈克

So I've been able to workaround the problem with help of a private method in the iOS runtime headers:

所以我已经能够借助iOS运行时头文件中的私有方法解决问题:

- (void)_reuseCell:(id)arg1;

My assumption is that this is where cells are being added back into the reuse queue. The hack to use this undocumented method looks like this:

我的假设是,这是将单元格添加回重用队列的位置。使用这个未记录的方法的黑客看起来像这样:

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];
}

The hack works! There's no stuttering when scrolling.

黑客工作!滚动时没有口吃。

The Question

问题

I don't think I'll be able to get past the App Store reviewers with this hack. Is there a way to do this without the use of undocumented methods? If not, is my only resort just to obfuscate the hack?

我不认为我能够通过这个黑客攻击App Store评论员。有没有办法在不使用未记录的方法的情况下做到这一点?如果没有,我唯一的办法就是混淆黑客行为?

1 个解决方案

#1


5  

Is there a way to do this without the use of undocumented methods?

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

If the problem is simply that it takes a long time to create the cells, then you can simply create a few extras and hold onto them in your view controller until the collection asks for them. Pre-allocate a few cells as you're doing in your code already, calling dequeueReusableCellWithReuseIdentifier: to get the collection to create them for you. Save these in an array in your view controller. Next, in your ...cellForItemAtIndexPath: method, if the array isn't empty remove a cell from the array and use it instead of asking the collection view for a reusable cell.

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

This should solve your problem by moving the point at which the cells are created without using any undocumented methods.

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

An alternative approach is to speed up the cell creation process so that you don't have to bother pre-allocating cells. Profile your code to see why your cells take so long to construct. Maybe you can simplify your cell structure by removing unnecessary views?

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

#1


5  

Is there a way to do this without the use of undocumented methods?

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

If the problem is simply that it takes a long time to create the cells, then you can simply create a few extras and hold onto them in your view controller until the collection asks for them. Pre-allocate a few cells as you're doing in your code already, calling dequeueReusableCellWithReuseIdentifier: to get the collection to create them for you. Save these in an array in your view controller. Next, in your ...cellForItemAtIndexPath: method, if the array isn't empty remove a cell from the array and use it instead of asking the collection view for a reusable cell.

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

This should solve your problem by moving the point at which the cells are created without using any undocumented methods.

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

An alternative approach is to speed up the cell creation process so that you don't have to bother pre-allocating cells. Profile your code to see why your cells take so long to construct. Maybe you can simplify your cell structure by removing unnecessary views?

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