IGListKit/Tests/Objects/IGTestDelegateController.m
Ryan Nystrom 74affe0887 Fixes crash when accessing a cell within working range updates
Summary:
I was able to build a unit test that reproduces the issue. We can avoid the crash by simply returning `nil` when accessing a cell while working range events are being vended.

There is definitely something weird going on here though. When debugging `cellForItemAtIndexPath:` I found:

```
(lldb) po indexPath
<NSIndexPath: 0xc000000000000516> {length = 2, path = 5 - 0}
(lldb) po [[self collectionView] numberOfSections]
11
```

So in theory we should be fine, right? But when I continue I get

```
*** Assertion failure in -[UICollectionViewData numberOfItemsBeforeSection:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.5.2/UICollectionViewData.m:611
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for number of items before section 5 when there are only 3 sections in the collection view'
```

There _were_ 3 sections in the UICV before the update, but the data source and structure powering
Closes https://github.com/Instagram/IGListKit/pull/216

Differential Revision: D4204625

Pulled By: rnystrom

fbshipit-source-id: 455ed199dfc115077e4294e2843016a50e179015
2016-11-18 09:59:01 -08:00

93 lines
3.2 KiB
Objective-C

/**
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "IGTestDelegateController.h"
#import "IGTestCell.h"
#import "IGTestObject.h"
@implementation IGTestDelegateController
- (instancetype)init {
if (self = [super init]) {
_willDisplayCellIndexes = [NSCountedSet new];
_didEndDisplayCellIndexes = [NSCountedSet new];
self.workingRangeDelegate = self;
}
return self;
}
- (NSInteger)numberOfItems {
if ([self.item.value isKindOfClass:[NSNumber class]]) {
return [self.item.value integerValue];
}
return 1;
}
- (CGSize)sizeForItemAtIndex:(NSInteger)index {
return CGSizeMake(self.collectionContext.containerSize.width, 10);
}
- (UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index {
IGTestCell *cell = [self.collectionContext dequeueReusableCellOfClass:IGTestCell.class
forSectionController:self atIndex:index];
[[cell label] setText:[NSString stringWithFormat:@"%@", self.item.value]];
[cell setDelegate:self];
if (self.cellConfigureBlock) {
self.cellConfigureBlock(self);
}
return cell;
}
- (void)didUpdateToObject:(id)object {
_updateCount++;
_item = object;
if (self.itemUpdateBlock) {
self.itemUpdateBlock();
}
}
- (id<IGListDisplayDelegate>)displayDelegate {
return self;
}
- (void)didSelectItemAtIndex:(NSInteger)index {}
#pragma mark - IGListDisplayDelegate
- (void)listAdapter:(IGListAdapter *)listAdapter willDisplaySectionController:(IGListSectionController <IGListSectionType> *)sectionController {
self.willDisplayCount++;
}
- (void)listAdapter:(IGListAdapter *)listAdapter didEndDisplayingSectionController:(IGListSectionController <IGListSectionType> *)sectionController {
self.didEndDisplayCount++;
}
- (void)listAdapter:(IGListAdapter *)listAdapter willDisplaySectionController:(IGListSectionController <IGListSectionType> *)sectionController
cell:(UICollectionViewCell *)cell
atIndex:(NSInteger)index {
[self.willDisplayCellIndexes addObject:@(index)];
}
- (void)listAdapter:(IGListAdapter *)listAdapter didEndDisplayingSectionController:(IGListSectionController <IGListSectionType> *)sectionController
cell:(UICollectionViewCell *)cell
atIndex:(NSInteger)index {
[self.didEndDisplayCellIndexes addObject:@(index)];
}
- (void)listAdapter:(IGListAdapter *)listAdapter didScrollSectionController:(IGListSectionController <IGListSectionType> *)sectionController {}
#pragma mark - IGListWorkingRangeDelegate
- (void)listAdapter:(IGListAdapter *)listAdapter sectionControllerWillEnterWorkingRange:(IGListSectionController<IGListSectionType> *)sectionController {
__unused UICollectionViewCell *cell = [self.collectionContext cellForItemAtIndex:0 sectionController:self];
}
- (void)listAdapter:(IGListAdapter *)listAdapter sectionControllerDidExitWorkingRange:(IGListSectionController<IGListSectionType> *)sectionController {}
@end