Fix crash when reloading section that gets deleted

Summary: Rare, but very real crash that occurs when a reload is manually queued and then the section gets deleted in a diff.

Reviewed By: jeremycohen

Differential Revision: D4267678

fbshipit-source-id: a5bedf77934ff85f76830e3f0123a993fc5d885c
This commit is contained in:
Ryan Nystrom 2016-12-05 11:48:24 -08:00 committed by Facebook Github Bot
parent e1d6f52552
commit 7c3d4999eb
3 changed files with 25 additions and 2 deletions

View file

@ -94,6 +94,8 @@ This release closes the [2.0.0 milestone](https://github.com/Instagram/IGListKit
- Skip reloading for objects that are not found when calling `-[IGListAdapter reloadObjects:]`. [Ryan Nystrom](https://github.com/rnystrom) (tbd)
- Fixes a crash when a reload is queued for an object that is deleted in the same runloop turn. [Ryan Nystrom](https://github.com/rnystrom) (tbd)
### Documentation
- We now have 100% documentation coverage. Docs been refined and clarified. [Jesse Squires](https://github.com/jessesquires) [(#207)](https://github.com/Instagram/IGListKit/pull/207)

View file

@ -234,8 +234,16 @@ void convertReloadToDeleteInsert(NSMutableIndexSet *reloads,
const NSUInteger from = hasObjects ? [result oldIndexForIdentifier:diffIdentifier] : idx;
const NSUInteger to = hasObjects ? [result newIndexForIdentifier:diffIdentifier] : idx;
[reloads removeIndex:from];
[deletes addIndex:from];
[inserts addIndex:to];
// if a reload is queued outside the diff and the object was inserted or deleted it cannot be
if (from != NSNotFound && to != NSNotFound) {
[deletes addIndex:from];
[inserts addIndex:to];
} else {
IGAssert([result.deletes containsIndex:idx],
@"Reloaded section %zi was not found in deletes with from: %zi, to: %zi, deletes: %@",
idx, from, to, deletes);
}
}];
}

View file

@ -384,4 +384,17 @@
XCTAssertTrue([inserts containsIndex:0]);
}
- (void)test_whenReloadingSection_whenSectionRemoved_thatConvertMethodCorrects {
NSArray *from = @[@"a", @"b", @"c"];
NSArray *to = @[@"a", @"c"];
IGListIndexSetResult *result = IGListDiff(from, to, IGListDiffEquality);
NSMutableIndexSet *reloads = [NSMutableIndexSet indexSetWithIndex:1];
NSMutableIndexSet *deletes = [NSMutableIndexSet new];
NSMutableIndexSet *inserts = [NSMutableIndexSet new];
convertReloadToDeleteInsert(reloads, deletes, inserts, result, from);
XCTAssertEqual(reloads.count, 0);
XCTAssertEqual(deletes.count, 0);
XCTAssertEqual(inserts.count, 0);
}
@end