I am writing an iOS8 application using the framework. I really love PHFetchResultChangeDetails. But I don’t understand something: when I save new photos in the camera frame using the following code, I return the inserts and changes. I expect only insertions.
To make it specific:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ PHAssetChangeRequest* newPhotoChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image]; PHAssetCollectionChangeRequest* albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:_album]; [albumChangeRequest addAssets:[NSArray arrayWithObject:newPhotoChangeRequest.placeholderForCreatedAsset]]; ...
The operation is to insert 3 photos using the above code. Before: 5 photos on ipad. After: 8 photos on the ipad. The breakpoint in the PHFetResultChangeDetails handler shows:
(lldb) po insertionIndexPaths <__NSArrayM 0x7913be10>( <NSIndexPath: 0x78e39020> {length = 2, path = 0 - 5}, <NSIndexPath: 0x78e3c910> {length = 2, path = 0 - 6}, <NSIndexPath: 0x78e39480> {length = 2, path = 0 - 7} )
-> GOOD: makes sense! these are the photos i just inserted (last 3 index paths).
(lldb) po changeIndexPaths <__NSArrayM 0x78e3c420>( <NSIndexPath: 0x78e3c7e0> {length = 2, path = 0 - 2}, <NSIndexPath: 0x78e3c7a0> {length = 2, path = 0 - 3}, <NSIndexPath: 0x78e3c7b0> {length = 2, path = 0 - 4} )
-> DO NOT UNDERSTAND: why are they considered "changed"? These are existing photos on the camera ... I did nothing to them.
Thank you for your help.
UPDATE: it looks like this might have something to do with the choice. I forgot to mention that this happens when some cells are already selected. I see that when new elements are inserted at the end of the View collection, some selected cells are not randomly selected - I think those that have changeIndexPaths. Wow, that sucks - I don’t see how my code can do this! Any clues?
UPDATE2: so it seems that false changeIndexPaths are always 3 indexPath immediately before the insertion paths (which are always at the end). Why?
UPDATE3: I also see failures in the UICollectionView performBatchUpdates when the data source is correctly updated in advance if there are both inserts and reloads. For example, when a change looks like this:
<PHFetchResultChangeDetails: 0x1742b91a0> before=<PHFetchResult: 0x1702b5d20> count=31, after=<PHFetchResult: 0x1702b5ea0> count=33, hasIncremental=1 deleted=(null), inserted=<NSMutableIndexSet: 0x17444aef0>[number of indexes: 2 (in 2 ranges), indexes: (30 32)], changed=<NSMutableIndexSet: 0x17444a9b0>[number of indexes: 4 (in 2 ranges), indexes: (27-29 31)], hasMoves=0
... then my application crashes to execBatchUpdates with the exception:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete item 31 from section 0 which only contains 31 items before the update'
Here is the performBatchUpdates code that I copied directly from the Apple documentation (!), So I see no reason why changeIndexPaths contains index 31, given that count = 31 before insertions:
[self.collectionView performBatchUpdates:^{ if( deletionIndexPaths.count ) [self.collectionView deleteItemsAtIndexPaths:deletionIndexPaths]; if( insertionIndexPaths.count ) [self.collectionView insertItemsAtIndexPaths:insertionIndexPaths]; if( changeIndexPaths.count ) [self.collectionView reloadItemsAtIndexPaths:changeIndexPaths]; if( moveBlock ) moveBlock(self.collectionView); } ...