PHFetchOption 键的 NSPredicate 语法

NSPredicate syntax for PHFetchOption keys

我正在 Swift 使用 PhotoKit 开发应用程序。

我对 Objective-C 几乎一无所知,我很难理解 NSPredicate 表达式的语法,这些表达式用于在整个库中过滤获取结果。

documentation for PHFetchOptions contains a table of keys that can be used in an NSPredicate via the PHFetchOptions.predicate. The documentation for PHFetchOptions.predicate 给出了如何使用它的示例,但我无法理解语法:

fetchOptions.predicate = [NSPredicate predicateWithFormat:@"(mediaSubtypes & %d) != 0 || (mediaSubtypes & %d) != 0", PHAssetMediaSubtypePhotoPanorama, PHAssetMediaSubtypeVideoHighFrameRate];

mediaSubtypes & %d

“&”在此上下文中的作用是什么?

PHAssetMediaSubtypePhotoPanorama

这是怎么回事?我知道这是指 PHAssetMediaSubtype.photoPanorama 但为什么这都是驼峰式的?

在我的特定示例中,我想通过执行以下操作来获取不为空的 PHAssetCollections:

    let smartAlbumsOptions = PHFetchOptions()
    smartAlbumsOptions.predicate = NSPredicate(format: "estimatedAssetCount > 0", argumentArray: nil)
    smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: smartAlbumsOptions)

我假设 PHFetchOptions 可以以某种方式将所有支持的键(即 estimatedAssetCount)的值插入到表达式字符串中,但我不明白如何做。

I can't make sense of the syntax ... What does the "&" do in this context?

看看文档:

Because an asset may have more than one subtype, you use these values as bit masks to identify an asset

如果你不习惯二进制运算,你肯定选了一个难的。

%d 是一个整数(PHAssetMediaSubtypePhotoPanoramaPHAssetMediaSubtypeVideoHighFrameRate 的原始值),它将与媒体子类型的原始值匹配,这也是一个整数——但是这是一个位掩码。这样它就可以表示多个值,这是有道理的,因为一个媒体可以同时具有多个子类型。

例如,值 6 (110) 代表 4 (100) 和 2 (10)。所以我们不能用简单的相等来表达这一点。如果我们想要 100,我们想要设置该位的任何值 ,但我们不关心任何其他位:100 是匹配项, 但是 110 也是一个匹配, 111 也是一个匹配, 101 也是一个匹配.

在Swift中,我们可以将其分解为一个选项集并对其进行设置contains。但是你不能在 Objective-C 中这样做,这是谓词的语言。

所以我们按位与 100 的位,从而将除一位以外的所有内容都更改为 0。例如110 & 100就是100,而111 & 100就是100,等等。但是 010 & 1000。好的,如果结果是 not 0,我们的位就不是 0。因此它是 1,我们有一场比赛。

how come this is all camelCased?

在 Objective C 中就是这样。看 https://developer.apple.com/documentation/photokit/phassetmediasubtype/phassetmediasubtypephotopanorama?language=objc

smartAlbumsOptions.predicate = NSPredicate(format: "estimatedAssetCount > 0", argumentArray: nil)

实际上只是省略了第二个参数:

smartAlbumsOptions.predicate = NSPredicate(format: "estimatedAssetCount > 0")

but I don't understand how.

这就是 NSPredicate 的工作原理。 Objective C 是高度动态和内省的,因此字符串可以表示属性的名称。阅读文档。 https://developer.apple.com/documentation/foundation/nspredicate