Fix bug with cell identifiers

Summary:
When we added the ability to register the same class with multiple reuse identifiers, forgot to adjust the `registeredClasses` set to reflect that. This resulted in a bug where the collection view could be asked for a cell of a class that had already been registered, but with a different reuse identifier, which would end in a crash.

This diff fixes the crash, I'll follow up with another diff that adds unit tests around this, but want to fix master ASAP.

Differential Revision: D9560338

fbshipit-source-id: e8df6fe5d9929b44842c6abc01d52064ccb4147e
This commit is contained in:
Jeremy Lawrence 2018-08-29 12:19:53 -07:00 committed by Facebook Github Bot
parent f699ea0e17
commit 3b19cfb9d7
5 changed files with 14 additions and 8 deletions

View file

@ -28,6 +28,8 @@ The changelog for `IGListKit`. Also see the [releases](https://github.com/instag
- Log instead of assert for duplicate diff identifiers to make code testable. [Adam Stern](https://github.com/adamastern) (tbd)
- Fixed crash when using `-[IGListCollectionContext dequeueReusableCellOfClass:withReuseIdentifier:forSectionController:atIndex:]` [Jeremy Lawrence](https://github.com/ziewvater) (tbd)
3.4.0
-----

View file

@ -94,7 +94,7 @@
// dump old registered section controllers in the case that we are changing collection views or setting for
// the first time
_registeredCellClasses = [NSMutableSet new];
_registeredCellIdentifiers = [NSMutableSet new];
_registeredNibNames = [NSMutableSet new];
_registeredSupplementaryViewIdentifiers = [NSMutableSet new];
_registeredSupplementaryViewNibNames = [NSMutableSet new];
@ -957,8 +957,8 @@
IGAssert(collectionView != nil, @"Dequeueing cell of class %@ with reuseIdentifier %@ from section controller %@ without a collection view at index %li", NSStringFromClass(cellClass), reuseIdentifier, sectionController, (long)index);
NSString *identifier = IGListReusableViewIdentifier(cellClass, nil, nil, reuseIdentifier);
NSIndexPath *indexPath = [self indexPathForSectionController:sectionController index:index usePreviousIfInUpdateBlock:NO];
if (![self.registeredCellClasses containsObject:cellClass]) {
[self.registeredCellClasses addObject:cellClass];
if (![self.registeredCellIdentifiers containsObject:identifier]) {
[self.registeredCellIdentifiers addObject:identifier];
[collectionView registerClass:cellClass forCellWithReuseIdentifier:identifier];
}
return [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

View file

@ -34,9 +34,9 @@
[debug addObject:[NSString stringWithFormat:@"Is prefetching enabled: %@", IGListDebugBOOL(self.collectionView.isPrefetchingEnabled)]];
}
if (self.registeredCellClasses.count > 0) {
[debug addObject:@"Registered cell classes:"];
[debug addObject:[self.registeredCellClasses description]];
if (self.registeredCellIdentifiers.count > 0) {
[debug addObject:@"Registered cell identifiers:"];
[debug addObject:[self.registeredCellIdentifiers description]];
}
if (self.registeredNibNames.count > 0) {

View file

@ -58,7 +58,11 @@ IGListBatchContext
@property (nonatomic, assign) BOOL isInUpdateBlock;
@property (nonatomic, strong, nullable) IGListSectionMap *previousSectionMap;
@property (nonatomic, strong) NSMutableSet<Class> *registeredCellClasses;
/**
Set of cell identifiers registered with the list context.
Identifiers are constructed with the `IGListReusableViewIdentifier` function.
*/
@property (nonatomic, strong) NSMutableSet<NSString *> *registeredCellIdentifiers;
@property (nonatomic, strong) NSMutableSet<NSString *> *registeredNibNames;
@property (nonatomic, strong) NSMutableSet<NSString *> *registeredSupplementaryViewIdentifiers;
@property (nonatomic, strong) NSMutableSet<NSString *> *registeredSupplementaryViewNibNames;

View file

@ -141,7 +141,7 @@
XCTAssertEqualObjects(identifier, @"UICollectionViewCell");
}
- (void)test_whenQueryingReusableIdentifierWithGivenIdentifier_tahtIdentifierEqualsGivenIdentifierAndClassName {
- (void)test_whenQueryingReusableIdentifierWithGivenIdentifier_thatIdentifierEqualsGivenIdentifierAndClassName {
NSString *identifier = IGListReusableViewIdentifier(UICollectionViewCell.class, nil, nil, @"MyCoolID");
XCTAssertEqualObjects(identifier, @"MyCoolIDUICollectionViewCell");
}