I have a UICollectionView
with a custom cell subclassing UICollectionViewCell
. And in the code I have done the following:
[self.collectionView_ registerClass:[AHPinterestCell class]
forCellWithReuseIdentifier:@"AHPinterestCell"];
this is what goes in my cellForItem
AHPinterestCell *cell =
(AHPinterestCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"AHPinterestCell"
forIndexPath:indexPath];
however, it seems that it's not reusing the cell. In my collection view per screen it is showing about 9-10 cells, however when I do infinite scroll and then I call insertItemsAtIndexPath
it calls the initWithFrame
method on my custom cell, while it should probably reuse the cells I already have. Why is this?
EDIT:
I am adding a sample demo project that illustrates the problem, the link to the xcode project can be found here. It's essentially doing an infinite scroll when you reach to the bottom, it just appends more stuff into it. But when you do so it's going to call the init method again.
Moreover, as @Fonix suggests, using a different cell identifier for each cell of your UITableView might solve your issue while keeping using cell reuse system. Edit : As you're talking about losing text content in your UITextField, maybe the single change to make is changing your @propery weak attribute to strong .
When the new cells appearing from the bottom need to be drawn they are dequeued from the reuse queue instead of initialising new instances, thereby keeping memory usage down. This is also why it's important that you configure the properties of your cell outside of the if (cell == nil) condition.
The reuse identifier is associated with a UITableViewCell object that the table-view's delegate creates with the intent to reuse it as the basis (for performance reasons) for multiple rows of a table view. It is assigned to the cell object in init(frame:reuseIdentifier:) and cannot be changed thereafter.
When we use, dequeueReusableCellWithIdentifier, the tableView just creates exactly the number of cells based on your table height and cell height. Suppose, if it shows 4 cells in the tabelView and rest you can see by scrolling, then memory for only 4 cells would be allocated at any given point of time.
In short, your code works fine. As expected, as cells scroll off the screen, they are eventually flagged as being available for reuse. And when you call dequeueReusableCellWithReuseIdentifier
, if there is a cell available for reuse, it will do so. If not, it creates one.
The time that you'll see a lot of cells being created is if you scroll fast or continually. But if you do short little scrolls, let go, pause, let the UI catch up and repeat, then you'll see very few cells being created.
I interpret this as meaning that iOS prioritizes the UI and the creation of new cells over the dequeuing of old cells, allowing their reuse. So if you flip quickly, it has trouble catching up and flagging old cells as available for reuse. This is probably not altogether bad, as this is probably what gives collection views such smooth flow. Flagging old cells for reuse is one of the less important things for iOS to do here. But clearly if memory is tight, this might be a problem.
By the way, if you put a NSLog
in dealloc
, too, you'll notice that when the UI finally catches up after doing a really fast scroll through the collection view, it clearly has some logic that says "gee, I've got more spare cells than I really need, I'm going to get rid of some of these." It's a pretty clever implementation, actually. A focus on speed, but with some memory optimizations that take place once the UI quiets down.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With