estimatedAssetCount returns 计数错误

estimatedAssetCount returns a wrong count

我需要显示相册中的图像数量。我正在使用以下代码获取相机胶卷相册。

let smartCollections = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .SmartAlbumUserLibrary, options: nil)
smartCollections.enumerateObjectsUsingBlock { object, index, stop in
    if let collection = object as? PHAssetCollection {
        print(collection.estimatedAssetCount)
    }
}

我在“照片”应用的相机胶卷中只有 28 张图像。但是 estimatedAssetCount 属性 returns 的值是 9223372036854775807!

只有 OS 创建的相册(如相册)才会出现这种情况。对于用户创建的常规相册,返回正确的值。我做错了什么还是这是一个错误?

如果是,是否有任何其他方法可以获取正确的图像计数?

应该看起来长一点。进入 PHAssetCollection 的头文件会显示这一小段信息。

These counts are just estimates; the actual count of objects returned from a fetch should be used if you care about accuracy. Returns NSNotFound if a count cannot be quickly returned.

所以我想这是预期的行为,而不是错误。所以我在下面添加了这个扩展方法以获得正确的图像计数并且它有效。

extension PHAssetCollection {
    var photosCount: Int {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.Image.rawValue)
        let result = PHAsset.fetchAssetsInAssetCollection(self, options: fetchOptions)
        return result.count
    }
}

9223372036854775807 在某些系统上是 NSNotFound 的值。 PHAssetCollection 的文档提到当计数无法 return 时它可以 return NSNotFound

如果您只想在必要时才进行抓取,您应该检查 NSNotFound:

let smartCollections = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .SmartAlbumUserLibrary, options: nil)
smartCollections.enumerateObjectsUsingBlock { object, index, stop in
    guard let collection = object as? PHAssetCollection else { return }

    var assetCount = collection.estimatedAssetCount
    if assetCount == NSNotFound {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.Image.rawValue)
        assetCount = PHAsset.fetchAssetsInAssetCollection(collection, options: fetchOptions).count
    }

    print(assetCount)
}

@Isuru 的回答略微修改为 Swift 5

extension PHAssetCollection {
    var photosCount: Int {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.image.rawValue)
        let result = PHAsset.fetchAssets(in: self, options: fetchOptions)
        return result.count
    }

    var videoCount: Int {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.video.rawValue)
        let result = PHAsset.fetchAssets(in: self, options: fetchOptions)
        return result.count
    }
}