Open knutigro opened 9 years ago
Hello,
I faced similar problem with one of my apps.
QBAssetsViewController.m line 398
__48-[QBAssetsViewController photoLibraryDidChange:]_block_invoke
Fatal Exception: NSInternalInconsistencyException attempt to delete item 57 from section 0 which only contains 57 items before the update
Thread : Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x1839fcf48 __exceptionPreprocess
1 libobjc.A.dylib 0x1985aff80 objc_exception_throw
2 CoreFoundation 0x1839fce18 +[NSException raise:format:]
3 Foundation 0x1848f0a1c -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
4 UIKit 0x1897af2e4 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:]
5 UIKit 0x1897b45c8 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:]
6 UIKit 0x1897b4444 -[UICollectionView _performBatchUpdates:completion:invalidationContext:]
7 UIKit 0x18917e99c -[UICollectionView performBatchUpdates:completion:]
8 QBImagePickerController 0x1011c32a4 __48-[QBAssetsViewController photoLibraryDidChange:]_block_invoke (QBAssetsViewController.m:398)
9 libdispatch.dylib 0x198dcd6e8 _dispatch_call_block_and_release
10 libdispatch.dylib 0x198dcd6a8 _dispatch_client_callout
11 libdispatch.dylib 0x198dd2db0 _dispatch_main_queue_callback_4CF
12 CoreFoundation 0x1839b41f8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
13 CoreFoundation 0x1839b2060 __CFRunLoopRun
14 CoreFoundation 0x1838e0ca0 CFRunLoopRunSpecific
15 GraphicsServices 0x18eb1c088 GSEventRunModal
16 UIKit 0x188ff8ffc UIApplicationMain
17 ... 0x1000d44b4 main (AppDelegate.swift:21)
18 libdyld.dylib 0x198dfe8b8 start
Looks like indexes calculation may be wrong somehow while updating. Do you have any assumptions why it crashes?
@burczyk actually I didn't really try to find a sollution to this crash yet but I probably should since its one of the biggest crash groups in my app for the moment. There is a thread here: http://stackoverflow.com/questions/29337765/crash-attempt-to-delete-and-reload-the-same-index-path which suggest it has something to do with iCloud sync. It also provides a sollution. I did try to reproduce the crash, like mentioned in this thread, but had no success... Maybe its time for a new try ...
I also didn't reproduce it yet. I only saw it in Crashlytics, 3 times. It probably doesn't matter but each crash occurred on iPhone 6 Plus running iOS 9.1.0 (although for different users, so it may be a coincidence).
I have been able to reproduce this today using following steps (taken from the accepted answer in this thread: http://stackoverflow.com/questions/29337765/crash-attempt-to-delete-and-reload-the-same-index-path):
It happens when the same index exist in both removedIndexes
and changedIndexes
.
I will create a pullrequest with a suggsted sollution.
It seemes like my original idea how to prevent this crash did not work :-( The search goes on...
same problem with my app, any news?
Hello i'm have the same problem
same issue, any solution?
bump
Has this library been abandoned? I bumped the same crash in the latest version
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x184a5ad8c __exceptionPreprocess
1 libobjc.A.dylib 0x183c145ec objc_exception_throw
2 CoreFoundation 0x184a5abf8 +[NSException raise:format:]
3 Foundation 0x18544afa0 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
4 UIKit 0x18e7b2174 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:]
5 UIKit 0x18e7b1abc -[UICollectionView _endUpdatesWithInvalidationContext:tentativelyForReordering:animator:]
6 UIKit 0x18e7b0c48 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:animator:]
7 UIKit 0x18e7b0aa4 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:]
8 UIKit 0x18e7b0a28 -[UICollectionView _performBatchUpdates:completion:invalidationContext:]
9 UIKit 0x18e7b09c0 -[UICollectionView performBatchUpdates:completion:]
10 QBImagePickerController 0x10663f534 __48-[QBAssetsViewController photoLibraryDidChange:]_block_invoke (QBAssetsViewController.m:397)
11 libdispatch.dylib 0x18434caa0 _dispatch_call_block_and_release
12 libdispatch.dylib 0x18434ca60 _dispatch_client_callout
13 libdispatch.dylib 0x18438dd80 _dispatch_main_queue_callback_4CF$VARIANT$armv81
14 CoreFoundation 0x184a03070 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
15 CoreFoundation 0x184a00bc8 __CFRunLoopRun
16 CoreFoundation 0x184920da8 CFRunLoopRunSpecific
17 GraphicsServices 0x186906020 GSEventRunModal
18 UIKit 0x18e940758 UIApplicationMain
19 Haraj 0x104ec2a1c main (main.m:16)
20 libdyld.dylib 0x1843b1fc0 start
Strange! 4 years and this issue still hasn't been solved. It's hard to reproduce. As someone said above, I also see it only in Crashlytics.
I added code to catch the exception and reload just reload the collectionView data in case if an exception occurs. This is not exactly a fix but I hope the crash is prevented.
@try {
[self.collectionView performBatchUpdates:^{
NSIndexSet *removedIndexes = [collectionChanges removedIndexes];
if ([removedIndexes count]) {
[self.collectionView deleteItemsAtIndexPaths:[removedIndexes qb_indexPathsFromIndexesWithSection:0]];
}
NSIndexSet *insertedIndexes = [collectionChanges insertedIndexes];
if ([insertedIndexes count]) {
[self.collectionView insertItemsAtIndexPaths:[insertedIndexes qb_indexPathsFromIndexesWithSection:0]];
}
NSIndexSet *changedIndexes = [collectionChanges changedIndexes];
if ([changedIndexes count]) {
[self.collectionView reloadItemsAtIndexPaths:[changedIndexes qb_indexPathsFromIndexesWithSection:0]];
}
} completion:NULL];
} @catch (NSException *exception) {
[self.collectionView reloadData];
} @finally {
//
}
this is how I fixed the code, the idea is to find if removeIndexes and changedIndexes has any union.
- (void)photoLibraryDidChange:(PHChange *)changeInstance {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
typeof(self) self = weakSelf;
if (!self) return;
// If we have incremental diffs, tell the collection view to animate insertions and deletions
void (^batchUpdated)(PHFetchResultChangeDetails *) = ^void(PHFetchResultChangeDetails *collectionChanges){
[self.collectionView performBatchUpdates:^{
NSIndexSet *removedIndexes = [collectionChanges removedIndexes];
if ([removedIndexes count]) {
[self.collectionView deleteItemsAtIndexPaths:[removedIndexes qb_indexPathsFromIndexesWithSection:0]];
}
NSIndexSet *insertedIndexes = [collectionChanges insertedIndexes];
if ([insertedIndexes count]) {
[self.collectionView insertItemsAtIndexPaths:[insertedIndexes qb_indexPathsFromIndexesWithSection:0]];
}
NSIndexSet *changedIndexes = [collectionChanges changedIndexes];
if ([changedIndexes count]) {
[self.collectionView reloadItemsAtIndexPaths:[changedIndexes qb_indexPathsFromIndexesWithSection:0]];
}
} completion:NULL];
};
BOOL (^shouldReload)(PHFetchResultChangeDetails *) = ^BOOL(PHFetchResultChangeDetails *collectionChanges){
if ([collectionChanges hasMoves]) { return YES; }
if ([collectionChanges hasIncrementalChanges] == NO) { return YES; }
if ([collectionChanges.removedIndexes containsAnyIndexOf:collectionChanges.changedIndexes]) {
return YES;
}
return NO;
};
PHFetchResultChangeDetails *collectionChanges = [changeInstance changeDetailsForFetchResult:self.fetchResult];
if (collectionChanges == nil) { return; }
self.fetchResult = [collectionChanges fetchResultAfterChanges];
if (shouldReload(collectionChanges)){
// We need to reload all if the incremental diffs are not available
[self.collectionView reloadData];
} else {
batchUpdated(collectionChanges);
}
[self resetCachedAssets];
});
}
Do not forget to add the next method to NSIndexSet category implementation
- (BOOL) containsAnyIndexOf:(NSIndexSet *)otherSet{
__block BOOL result = NO;
[otherSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
if ([self containsIndex:idx]){
result = YES;
*stop = YES;
}
}];
return result;
}
Info: *\ Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete and reload the same index path (<NSIndexPath: 0x18a62f00> {length = 2, path = 0 - 94})'
Exception Type: SIGABRT
Hardware Model: iPad3,4 OS Version: iPhone OS 8.4 (12H143)
Exception Type: SIGABRT Exception Codes: #0 at 0x316addf0 Crashed Thread: 0
Application Specific Information: *\ Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete and reload the same index path (<NSIndexPath: 0x18a62f00> {length = 2, path = 0 - 94})'
Last Exception Backtrace: 0 CoreFoundation 0x22973fef exceptionPreprocess + 127 1 libobjc.A.dylib 0x31031c8b objc_exception_throw + 36 2 CoreFoundation 0x22973ec5 +[NSException raise:format:arguments:] + 102 3 Foundation 0x23673f17 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 88 4 UIKit 0x265f0711 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:] + 1342 5 UIKit 0x265f492f -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:] + 404 6 UIKit 0x265f4793 -[UICollectionView _performBatchUpdates:completion:invalidationContext:] + 28 7 UIKit 0x261b1617 -[UICollectionView performBatchUpdates:completion:] + 28 8 Foap 0x002b6b01 __48-[QBAssetsViewController photoLibraryDidChange:]_block_invoke (QBAssetsViewController.m:403) 9 libdispatch.dylib 0x315c22e3 _dispatch_call_block_and_release + 8 10 libdispatch.dylib 0x315c22cf _dispatch_client_callout + 20 11 libdispatch.dylib 0x315c5d2f _dispatch_main_queue_callback_4CF + 1328 12 CoreFoundation 0x22939609 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 6 13 CoreFoundation 0x22937d09 __CFRunLoopRun + 1510 14 CoreFoundation 0x22884201 CFRunLoopRunSpecific + 474 15 CoreFoundation 0x22884013 CFRunLoopRunInMode + 104 16 GraphicsServices 0x2a243201 GSEventRunModal + 134 17 UIKit 0x26050a09 UIApplicationMain + 1438 18 Foap 0x0003b2ab main (main.m:15) 19 libdyld.dylib 0x315e3aaf start + 0