UICollectionView do not reuse cells

15,164

Solution 1

Update 2:
It turns out that this answer is not correct. Please see the answer below or by clicking this link https://stackoverflow.com/a/20147799/814389 instead.


Update

So I have revisited this answer since as I have found out a little more about this bug..

I grabbed all the devices I had available to me and ran the same tests on each one and these were the results:

DEVICE          OS Version      CELL REUSE
=============   =============   =============
iPad 4          7.0.0           YES
iPad 4          7.0.3           YES
iPad 3          7.0.3           NO
iPad 2          7.0.3           NO
iPad Mini       7.0.0           YES
iPad Mini       7.0.3           YES
iPhone 5s       7.0.3           YES
iPhone 4        7.0.2           YES
iPhone 4        7.0.3           YES

As you can see, it looks like for some reason cell reuse is not working on older iPads (ones that aren't capable of rendering the blurs).

I initially thought that Apple may have just prevented reuse on older iPads due to some sort of performance issue but if that was to have made sense, the iPhone 4 would also show the same results.

To get around this issue in my application, I have a NSMutableDictionary in my collectionViewController and I am storing my cells in there with the key being the indexPath.. In my case this is OK as I only have around 9 cells and their indexPaths never change but if you needed something more flexible then maybe it would be a good idea to checkout PSTCollectionView (https://github.com/steipete/PSTCollectionView)


Just tested this out on a physical device.. and it seems to work fine on both iOS 7 and 6 but not iOS 7 Simulator!!!

Just put some logs in the collectionView sample:

@implementation Cell

- (id)initWithCoder:(NSCoder *)aDecoder
{
    NSLog(@"%s",__func__);
    self = [super initWithCoder:aDecoder];
    if (self)
    {
        CustomCellBackground *backgroundView = [[CustomCellBackground alloc] initWithFrame:CGRectZero];
        self.selectedBackgroundView = backgroundView;
    }
    return self;
}

-(void)prepareForReuse
{
    NSLog(@"%s",__func__);
}

-(void)dealloc
{
    NSLog(@"%s",__func__);
}

@end

Then scrolled to the bottom on all three devices and this was the output:

iOS 7 Simulator

2013-10-09 17:42:45.798 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:45.807 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:45.811 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:45.841 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:45.844 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:45.848 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:45.852 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:45.857 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.080 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.083 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.181 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.183 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.208 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.208 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.214 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.218 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.245 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.246 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.264 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.268 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.289 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.290 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.317 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.322 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.343 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.344 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.364 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.367 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.401 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.402 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.430 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.432 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.472 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.472 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.498 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.505 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.561 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.562 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.585 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.587 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.624 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.624 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.669 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.674 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.797 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.799 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.809 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.809 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.810 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.810 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.964 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.966 CollViewSmpl[9547:a0b] -[Cell initWithCoder:]
2013-10-09 17:42:47.987 CollViewSmpl[9547:a0b] -[Cell dealloc]
2013-10-09 17:42:47.987 CollViewSmpl[9547:a0b] -[Cell dealloc]

iOS 6 Device (iPhone 5)

2013-10-09 17:45:42.173 CollViewSmpl[187:907] -[Cell initWithCoder:]
2013-10-09 17:45:42.191 CollViewSmpl[187:907] -[Cell initWithCoder:]
2013-10-09 17:45:42.205 CollViewSmpl[187:907] -[Cell initWithCoder:]
2013-10-09 17:45:42.217 CollViewSmpl[187:907] -[Cell initWithCoder:]
2013-10-09 17:45:42.230 CollViewSmpl[187:907] -[Cell initWithCoder:]
2013-10-09 17:45:42.242 CollViewSmpl[187:907] -[Cell initWithCoder:]
2013-10-09 17:45:42.253 CollViewSmpl[187:907] -[Cell initWithCoder:]
2013-10-09 17:45:42.264 CollViewSmpl[187:907] -[Cell initWithCoder:]
2013-10-09 17:45:43.630 CollViewSmpl[187:907] -[Cell initWithCoder:]
2013-10-09 17:45:43.640 CollViewSmpl[187:907] -[Cell initWithCoder:]
2013-10-09 17:45:43.697 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:43.706 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:43.777 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:43.791 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:43.844 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:43.855 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:43.927 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:43.937 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:44.027 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:44.037 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:44.144 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:44.155 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:44.311 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:44.324 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:44.560 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:44.571 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:45.027 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:45.040 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:45.397 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:45.407 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:45.494 CollViewSmpl[187:907] -[Cell prepareForReuse]
2013-10-09 17:45:45.503 CollViewSmpl[187:907] -[Cell prepareForReuse]

iOS 7 Device (iPhone 5s)

2013-10-09 17:44:37.603 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:38.015 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:38.029 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:38.037 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:38.045 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:38.053 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:38.061 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:38.071 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:39.470 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:39.483 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:39.535 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.540 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.583 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.587 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.633 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.637 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.683 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.688 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.733 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.737 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.783 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:39.791 CollViewSmpl[871:60b] -[Cell initWithCoder:]
2013-10-09 17:44:39.866 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.870 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.933 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:39.938 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:40.033 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:40.036 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:40.149 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:40.152 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:40.300 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:40.304 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:40.650 CollViewSmpl[871:60b] -[Cell prepareForReuse]
2013-10-09 17:44:40.652 CollViewSmpl[871:60b] -[Cell prepareForReuse]

You can tell that there have been some changes between reuse in iOS 6 and 7 because 1) It doesn't work in the simulator and 2) If you do a really fast scroll to begin with, the cells aren't initially ready for reuse so it has to create a new one to compensate where iOS 6 didn't (see my logs).

There goes half of my day trying to fix a bug that only happens on the simulator.

Solution 2

I was experiencing the same exact issue on my iPad 3 today (just one out of three iPad 3 I tested out), and I found out it is related to global Accessibility settings. The solution is to double check that every option in accessibility panel is disabled. I think that some options (like bigger fonts, for example) could stay enabled, but I haven't checked which one in details.

Explanation

Looking at the stack trace you can see this:

#0  0x003121ce in -[MyCollectionViewCell initWithFrame:]
#1  0x32f945ec in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:]
#2  0x04466656 in -[UICollectionViewAccessibility(SafeCategory) _dequeueReusableViewOfKind:withIdentifier:forIndexPath:]
#3  0x32f9414a in -[UICollectionView dequeueReusableCellWithReuseIdentifier:forIndexPath:]
#4  0x001767cc in -[MyCollectionView collectionView:cellForItemAtIndexPath:]

As you can see there is a call to -[UICollectionViewAccessibility(SafeCategory) _dequeueReusableViewOfKind:withIdentifier:forIndexPath:] that references something about Accessibility. So I went to Accessibility settings in Settings app, and I found out that my setting for Accessibility Shortcut was "switch control" instead of nothing. So I disabled it, I ran again the app and my stack trace now was fine:

#0  0x00313658 in -[MyCollectionViewCell prepareForReuse]
#1  0x32f942e6 in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:]
#2  0x32f9414a in -[UICollectionView dequeueReusableCellWithReuseIdentifier:forIndexPath:]
#3  0x001767cc in -[MyCollectionView collectionView:cellForItemAtIndexPath:]

Solution 3

This is a known issue in iOS 7: http://openradar.appspot.com/15357491

Share:
15,164

Related videos on Youtube

in.disee
Author by

in.disee

Updated on June 25, 2022

Comments

  • in.disee
    in.disee about 2 years

    I am having trouble with reuse cells and UICollectionView on iOS 7. My code works fine on iOS 6 but in iOS 7 it does not reuse the cell after calling dequeueReusableCellWithReuseIdentifier (do not call prepareForReuse).

    Even this code https://developer.apple.com/library/ios/samplecode/CollectionView-Simple/Introduction/Intro.html#//apple_ref/doc/uid/DTS40012860 does not reuse cell on iOS7 (but works well on iOS6), on every dequeueReusableCellWithReuseIdentifier it creates a new cell and deallocates the old one. Is there some new stuff that prevents cells to be reused?

    My cells are big enough that they it is very inefficient to not reuse them. I've notice lag on iOS 7, but not on iOS 6, because they are not being reused in iOS 7.

    • liamnichols
      liamnichols over 10 years
      I have the exact same issue! Thought it was my setup or something but I've just tested on the apple sample code and am having the same results!
    • Avba
      Avba over 10 years
      You got +1 and I got -1. Help me out for same question
    • Alessandro Orrù
      Alessandro Orrù over 10 years
      @in.disee could you please set my recent answer as the right one, in order to be more evident since it's really the right answer? thank you
  • in.disee
    in.disee over 10 years
    Thanks, man. Half of my day also wastes, make same logging as you. There'we no devices around to test =)
  • stevesw
    stevesw over 10 years
    I'm having the opposite problem: it works fine in the iPad simulator, but is not reusing cells on my 3rd gen iPad running iOS 7.0.3.
  • liamnichols
    liamnichols over 10 years
    Have you tested with the apple sample code or is it your own code? I haven't had a chance to check on 7.0.3 myself yet
  • stevesw
    stevesw over 10 years
    I've tested on both the Apple sample project linked above, and in my own project. Same behavior on both. Cells are not reused on the device, but they are reused in the simulator.
  • liamnichols
    liamnichols over 10 years
    @StevenWei.. Just tested iPhone 4" Retina 7.0 Simulator and iPhone 5s 7.0.3 and both are reusing cells correctly (on the apple sample code).. Are you compiling in Xcode 5.0.1?
  • liamnichols
    liamnichols over 10 years
    @StevenWei I have just done a side by side test using the sample project again on both an iPad 3 and an iPad 4 running iOS 7.0.3... Looks like you was right, the iPad 3 doesn't reuse cells however the iPad 4 does! I'm going to investigate further and update my answer
  • stevesw
    stevesw over 10 years
    @L14M333 Thanks for the extra detective work. I am seeing the same behavior: cell reuse works fine on iPhone 5S 7.0.3, iPad Air 7.0.3, and iPhone 4" Retina Simulator, but fails on iPad 3. Between this, the memory leaks when you have more than one type of cell/supplementary view registered, and the crashes in performBatchUpdates, I'm seriously starting to regret using a collection view...
  • osxdirk
    osxdirk over 10 years
    We are seeing no cell reuse in our custom app on iPhone 5s, 7.0.3. -prepareForReuse is never called and instruments shows 25% of time for cell nib loading.
  • Alessandro Orrù
    Alessandro Orrù over 10 years
    Hello everyone, I just experienced the same issue, but my tests were weirder than your tests, since using three different iPad 3 just one wasn't reusing cells, while the other two yes. This is related to some accessibility settings, see my answer below to check it out ;)
  • liamnichols
    liamnichols over 10 years
    Good find! Have you tested it on an iPad 4 yet? I'm not near any devices for a while so can't try it out myself
  • Alessandro Orrù
    Alessandro Orrù over 10 years
    No, sorry, unfortunately I don't have one either
  • liamnichols
    liamnichols over 10 years
    I just tested this on an iPad Mini and the same thing happens! It also turns out that the iPad 3 I tested on also had a shortcut enabled! Good find! There is also a radar to duplicate if you get the time rdar://15357491
  • stevesw
    stevesw over 10 years
    Very interesting, thanks for tracking this down. I have confirmed that unchecking all options under Accessibility Shortcut fixes the prepareForReuse problem on my iPad 3. How random...
  • Stephen Tallent
    Stephen Tallent over 10 years
    Oh man. I'm glad i stumbled upon this. Was driving me crazy why it wasn't reusing my cells. Thanks a ton for posting. Absolutely was the shortcut for me.
  • Sebastien Martin
    Sebastien Martin over 10 years
    I'm currently seeing this behaviour on my simulator and can confirm that the call stack includes the accessibility line, but I don't have the Accessibility Shortcut option in my simulator settings. Using iPad sim for iOS 7.0.3 (11B508). Any ideas?
  • AndrewK
    AndrewK almost 9 years
    How did you allocate that cells for keeping them in nsdictionary? I am trying to do that, and get this: "the cell returned from -collectionView:cellForItemAtIndexPath: does not have a reuseIdentifier - cells must be retrieved by calling -dequeueReusableCellWithReuseIdentifier:forIndexPath:"
  • Joey Carson
    Joey Carson over 8 years
    I'm seeing this same behavior on iOS 9.1 on an iPad Air. The memory usage is out of hand due to the cells not being reused. Cells are also not removed from the collection view either, so they appear on top of each other as well.