我正在使用Photos框架编写iOS8应用程序。我真的很喜欢PHFetchResultChangeDetails。 但有一些我不明白的事情:当我使用以下代码将新照片保存到相机胶卷时,我会回来插入和更改。我希望只插入。
使其具体化:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest* newPhotoChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
PHAssetCollectionChangeRequest* albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:_album];
[albumChangeRequest addAssets:[NSArray arrayWithObject:newPhotoChangeRequest.placeholderForCreatedAsset]];
...
操作是使用上面的代码插入3张照片。之前:ipad上的5张照片。之后:ipad中的8张照片。 PHFetResultChangeDetails处理程序上的断点显示:
(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}
)
- &GT;好的:有道理!这些是我刚插入的照片(最后3个索引路径)。
(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}
)
- &GT;不要理解:为什么这些被认为是“改变了”?这些是相机胶卷上的现有照片......我没有对它们做任何事情。
感谢您的帮助。
更新:看起来它可能与选择有关。我忽略了提到,当已经选择了一些细胞时会发生这种情况。我所看到的是,当在collectionView的末尾插入新项目时,一些选定的单元格被随机取消选择 - 我认为那些具有changeIndexPaths。哇,太糟糕了 - 我看不出我的代码是如何做到的!任何提示?
UPDATE2:所以,看起来虚假的changeIndexPaths总是直接在插入路径之前的3个indexPaths(总是在结尾处)。为什么呢?!
UPDATE3:我还看到UICollectionView的performBatchUpdates崩溃,如果数据源事先是正确的,如果有插入和重新加载的话。例如,当更改看起来像这样:
<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
...然后我的应用程序在performBatchUpdates中崩溃,但有例外:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete item 31 from section 0 which only contains 31 items before the update'
这是performBatchUpdates的代码,我直接从Apple文档(!)复制,因此我认为没有理由为changeIndexPaths包含索引31,因为在插入之前,count = 31:
[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);
} ...
答案 0 :(得分:3)
回复:更新3
尽管示例代码说的是,changedIndexes不能像这样在performBatchUpdates中使用。
索引PHFetchResultChangeDetails.changedIndexes相对于删除removedIndexes中的索引之后的原始获取结果,并且添加了insertedIndexes中的新索引之后的。
UITableView和UICollectionView API要求reloadItems *方法在批量更新中调用时,之前的索引任何其他更改。
要修复此调用,请在批量更新之外重新加载和移动条目,例如:
[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);