zhangao0086 / DKImagePickerController

Image Picker Controller for iOS written in Swift 4 & 5.
MIT License
1.49k stars 471 forks source link

NSInternalInconsistency crash in DKAssetGroupDetailVC #579

Open avinpr opened 5 years ago

avinpr commented 5 years ago

Bug:

Crash (NSInternalInconsistencyException) occurring in DKImagePickerController library when deleting photos from any album and re-engaging with app. The problem appears to be related to calling “performBatchUpdates” and receiving incorrect information on the updates that were made. This crash can also be reproduced in the sample app.

Steps to recreate:

  1. Start the sample app.
  2. Select any of the “Basic” options (eg. Pick Any, Single Select, Select All etc.)
  3. Select “Start” on the next screen to bring up the Image Picker screen.
  4. Select a photo on the Image Picker screen.
  5. Put the app in the background and navigate to the “Photos” app on the device.
  6. Delete the same photo that was previously selected within the sample app.
  7. Now, switch back to the sample app.
  8. It crashes right away.

Sample Error Message:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (47) must be equal to the number of items contained in that section before the update (48), plus or minus the number of items inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).

Excerpt from Stack trace:

CoreFoundation 0x0000000182527ef8 __exceptionPreprocess + 228 libobjc.A.dylib 0x00000001816f5a3c objc_exception_throw + 52 CoreFoundation 0x000000018243c068 +[NSException raise:format:arguments:] + 100 Foundation 0x0000000182f283dc -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 108 UIKitCore 0x00000001aed5db50 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:] + 12836 UIKitCore 0x00000001aed64ddc -[UICollectionView _endUpdatesWithInvalidationContext:tentativelyForReordering:animator:] + 88 UIKitCore 0x00000001aed65114 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:animator:] + 384 UIKitCore 0x00000001aed64f70 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:] + 92 UIKitCore 0x00000001aed64ef4 -[UICollectionView _performBatchUpdates:completion:invalidationContext:] + 80 UIKitCore 0x00000001aed64e30 -[UICollectionView performBatchUpdates:completion:] + 60 DKImagePickerController 0x0000000105a48424 function signature specialization <Arg[0] = Dead> of DKImagePickerController.DKAssetGroupDetailVC.imagePickerControllerDidDeselect(assets: [DKImagePickerController.DKAsset]) -> () + 280 DKImagePickerController 0x0000000105a43504 @objc DKImagePickerController.DKAssetGroupDetailVC.imagePickerControllerDidDeselect(assets: [DKImagePickerController.DKAsset]) -> () + 68 DKImagePickerController 0x0000000105a5c930 closure #1 () -> () in DKImagePickerController.DKImageBaseManager.notify(with: ObjectiveC.Selector, object: Swift.AnyObject?, objectTwo: Swift.AnyObject?) -> () + 280 DKImagePickerController 0x0000000105a5c6a8 DKImagePickerController.DKImageBaseManager.notify(with: ObjectiveC.Selector, object: Swift.AnyObject?, objectTwo: Swift.AnyObject?) -> () + 220 DKImagePickerController 0x0000000105a7c830 DKImagePickerController.DKImagePickerController.deselect(asset: DKImagePickerController.DKAsset) -> () + 1372 DKImagePickerController 0x0000000105a48774 function signature specialization <Arg[0] = Dead> of DKImagePickerController.DKAssetGroupDetailVC.group(groupId: Swift.String, didRemoveAssets: [DKImagePickerController.DKAsset]) -> () + 480 DKImagePickerController 0x0000000105a43590 @objc DKImagePickerController.DKAssetGroupDetailVC.group(groupId: Swift.String, didRemoveAssets: [DKImagePickerController.DKAsset]) -> () + 88 DKImagePickerController 0x0000000105a5c930 closure #1 () -> () in DKImagePickerController.DKImageBaseManager.notify(with: ObjectiveC.Selector, object: Swift.AnyObject?, objectTwo: Swift.AnyObject?) -> () + 280

Notes:

devandanger commented 5 years ago

@avinpr and I looked at this and he pointed out this was the original commit which introduced this for performBatchUpdates. @zhangao0086 do you know what the intent or use case was for this particular change?... In what scenario was the UI performance really poor?

zhangao0086 commented 5 years ago

Hi @devandanger @avinpr This issue was fixed in the develop branch. Could you give it a try?

pod 'DKImagePickerController', :git => 'https://github.com/zhangao0086/DKImagePickerController.git', :branch => 'develop'

Then clean the project and rebuild