The problem is in updating visible cell nodes after it's deletion.
Dispatched block [self performSelector:@selector(updateVisibleNodeIndexPaths) withObject:nil afterDelay:0 inModes:@[ NSDefaultRunLoopMode ]];
is performing right after DELETE_NODES(_nodes, indexPaths, animationOption); in ASDataController::reloadRowsAtIndexPaths.
Actually, there is no possibility to say when updateVisibleNodeIndexPaths will be dispatched exactly.
We have empty _nodes array at this moment and NSRangeException raises
2015-06-15 15:06:51.448 NFLMobile[49145:813629] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectsAtIndexes:]: index 4 in index set beyond bounds for empty array'
*** First throw call stack:
(
0 CoreFoundation 0x0000000104693c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001082a0bb7 objc_exception_throw + 45
2 CoreFoundation 0x00000001045dd413 -[NSArray objectsAtIndexes:] + 979
3 NFLMobile 0x0000000102e2dde5 __ASFindElementsInMultidimensionalArrayAtIndexPaths_block_invoke + 55
4 NFLMobile 0x0000000102e2d893 _ZL52ASRecursivelyUpdateMultidimensionalArrayAtIndexPathsP14NSMutableArrayPK7NSArrayRmP11NSIndexPathmU13block_pointerFvS0_P10NSIndexSetmE + 656
5 NFLMobile 0x0000000102e2d729 _ZL52ASRecursivelyUpdateMultidimensionalArrayAtIndexPathsP14NSMutableArrayPK7NSArrayRmP11NSIndexPathmU13block_pointerFvS0_P10NSIndexSetmE + 294
6 NFLMobile 0x0000000102e2dcfc ASFindElementsInMultidimensionalArrayAtIndexPaths + 322
7 NFLMobile 0x0000000102e171f0 -[ASDataController nodesAtIndexPaths:] + 69
8 NFLMobile 0x0000000102e370ef -[ASTableView rangeController:nodesAtIndexPaths:] + 31
9 NFLMobile 0x0000000102e338b9 -[ASRangeController updateVisibleNodeIndexPaths] + 1161
10 Foundation 0x0000000107d011e5 __NSFireDelayedPerform + 387
11 CoreFoundation 0x00000001045fb174 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
12 CoreFoundation 0x00000001045fad35 __CFRunLoopDoTimer + 1045
13 CoreFoundation 0x00000001045bcd3d __CFRunLoopRun + 1901
14 CoreFoundation 0x00000001045bc366 CFRunLoopRunSpecific + 470
15 GraphicsServices 0x000000010a773a3e GSEventRunModal + 161
16 UIKit 0x000000010590a900 UIApplicationMain + 1282
17 NFLMobile 0x0000000102acbccf main + 127
18 libdyld.dylib 0x0000000109724145 start + 1
19 ??? 0x0000000000000001 0x0 + 1
)
I've found a way to fix this issue by adding a check on array count in callback. It's just a stub, may be the problem should have a different solution.
NSArray *ASFindElementsInMultidimensionalArrayAtIndexPaths(NSMutableArray *mutableArray, NSArray *indexPaths) {
NSUInteger curIdx = 0;
NSIndexPath *indexPath = [[NSIndexPath alloc] init];
NSMutableArray *deletedElements = [[NSMutableArray alloc] initWithCapacity:indexPaths.count];
if (!indexPaths.count) {
return deletedElements;
}
ASRecursivelyUpdateMultidimensionalArrayAtIndexPaths(mutableArray, indexPaths, curIdx, indexPath, [indexPaths[0] length], ^(NSMutableArray *arr, NSIndexSet *indexSet, NSUInteger idx) {
if (arr.count > 0) // <<< check count
{
[deletedElements addObjectsFromArray:[arr objectsAtIndexes:indexSet]];
}
});
ASDisplayNodeCAssert(curIdx == indexPaths.count, @"Indexpath is out of range !");
return deletedElements;
}
The problem is in updating visible cell nodes after it's deletion.
Dispatched block
[self performSelector:@selector(updateVisibleNodeIndexPaths) withObject:nil afterDelay:0 inModes:@[ NSDefaultRunLoopMode ]];is performing right after
DELETE_NODES(_nodes, indexPaths, animationOption);inASDataController::reloadRowsAtIndexPaths.Actually, there is no possibility to say when
updateVisibleNodeIndexPathswill be dispatched exactly.We have empty
_nodesarray at this moment and NSRangeException raisesI've found a way to fix this issue by adding a check on array count in callback. It's just a stub, may be the problem should have a different solution.