PHPhotoLibrary - photoLibraryDidChange 在 Swift 中多次调用

Posted

技术标签:

【中文标题】PHPhotoLibrary - photoLibraryDidChange 在 Swift 中多次调用【英文标题】:PHPhotoLibrary - photoLibraryDidChange called multiple times in Swift 【发布时间】:2017-03-07 20:02:00 【问题描述】:

我有以下代码:

override func viewDidLoad() 
    ........
    phphotoLibrary.shared().register(self)

我已经实现了PHPhotoLibraryDidChangeObserver

我的问题是,如果设备库中的某些内容发生更改,photoLibraryDidChange 方法会被多次调用。 这是该函数的代码:

func photoLibraryDidChange(_ changeInstance: PHChange) 
    DispatchQueue.main.async(execute: 
        self.updateFetchResult();
    )

你知道为什么这个方法会被执行multiple 次吗?

【问题讨论】:

您找到解决方案了吗?我刚刚实现了PHPhotoLibraryChangeObserver 协议,并在查看我的UICollectionView 的同时通过截屏对其进行了测试。我注意到当我截屏时,photoLibraryDidChange(_ changeInstance: PHChange) 被调用了两次。 也在寻找答案。在我的代码中, photoLibraryDidChange 被调用了大约 3 次。但大多数时候只是没有实际变化 【参考方案1】:

您找到解决方案了吗? 这解决了mi问题:

首先,如果您使用此方法,请在调用PHAsset.fetchAssets(with:options:) 时保存您的PHFetResult<PHAsset>

之后,使用您的PHFetResult<PHAsset> 变量来验证获取结果是否在photoLibraryDidChange: 方法中发生了变化。第一次调用此方法时,您必须更新为集合视图或表格视图。之后,您的 fetch 结果没有改变,所以......您没有什么要更新的。

这是我的完整代码:

let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]

self.fetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)

.
.
.

extension YourViewController: PHPhotoLibraryChangeObserver 

    func photoLibraryDidChange(_ changeInstance: PHChange) 
        if let _fetchResult = self.fetchResult, let _ = changeInstance.changeDetails(for: _fetchResult) 
            DispatchQueue.main.async 
                self.getPhotos()
            
        
    


希望对您有所帮助!

【讨论】:

【参考方案2】:
extension YourViewController: PHPhotoLibraryChangeObserver 

    func photoLibraryDidChange(_ changeInstance: PHChange) 
        if let _fetchResult = self.fetchResult, let resultDetailChanges = changeInstance.changeDetails(for: _fetchResult) 
            let addedItems = resultDetailChanges.insertedObjects
            let deletedItems = resultDetailChanges.removedObjects
            let changedItems = resultDetailChanges.changedObjects
            if resultDetailChanges.hasIncrementalChanges && (addedItems.count > 0 || deletedItems.count > 0 || changedItems.count > 0)
                DispatchQueue.main.async 
                    self.getPhotos()
                
            
        
    


检查resultDetailChanges.hasIncrementalChanges 和(添加、删除、更改的资产)计数将保护避免多次调用。

【讨论】:

仍然为我打了两次电话【参考方案3】:

试试这个方法

extension YourViewController: PHPhotoLibraryChangeObserver 

        func photoLibraryDidChange(_ changeInstance: PHChange) 
            if let _fetchResult = self.fetchResult, let resultDetailChanges = changeInstance.changeDetails(for: _fetchResult) 
                let insertedObjects = resultDetailChanges.insertedObjects
                let removedObjects = resultDetailChanges.removedObjects
                let changedObjects = resultDetailChanges.changedObjects.filter( 
                    return changeInstance.changeDetails(for: $0)?.assetContentChanged == true
                )
                if resultDetailChanges.hasIncrementalChanges && (insertedObjects.count > 0 || removedObjects.count > 0 || changedObjects.count > 0)
                    DispatchQueue.main.async 
                        self.getPhotos()
                    
                
            
        

    

【讨论】:

以上是关于PHPhotoLibrary - photoLibraryDidChange 在 Swift 中多次调用的主要内容,如果未能解决你的问题,请参考以下文章

“PHPhotoLibrary.requestAuthorization”不在 iOS 9 中询问权限

如何使用 PHPhotoLibrary 获取照片的日期

PHPhotoLibrary 获取相册和照片信息

在 PHPhotoLibrary 中,photoLibraryDidChange 不会通知所有更新

重置 [PHPhotoLibrary 授权状态]

如何从 IOS 中的 PHPhotoLibrary 获取 ref url?