我正在Swift中使用PhotoKit开发一个应用程序。
我对Objective-C几乎一无所知,很难理解NSPredcate表达式的语法,这些表达式用于在整个库中过滤获取结果。
PHFetchOptions的文档包含一个键表,这些键可以通过PHFetchOptions.predicate在NSPreddice中使用。PHFetchoptionss.predice的文档给出了如何使用它的示例,但我无法理解语法:
fetchOptions.predicate = [NSPredicate predicateWithFormat:@"(mediaSubtypes & %d) != 0 || (mediaSubtypes & %d) != 0", PHAssetMediaSubtypePhotoPanorama, PHAssetMediaSubtypeVideoHighFrameRate];
media子类型&%d
";在这种情况下做什么?
PHassetMedia子类型PhotoPanorama
这里发生了什么?我知道这是指PHAssetMediaSubtype.photoPanorama,但为什么这都是基于camel的?
在我的特定示例中,我想通过这样做来获取不为空的PHAssetCollections:
let smartAlbumsOptions = PHFetchOptions()
smartAlbumsOptions.predicate = NSPredicate(format: "estimatedAssetCount > 0", argumentArray: nil)
smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: smartAlbumsOptions)
我假设PHFetchOptions可以以某种方式将所有支持的键的值(即estimatedAssetCount)插入到表达式字符串中,但我不明白如何插入。
我搞不懂语法。。。什么是"";在这种情况下做什么?
查看文档:
因为一个资产可能有多个子类型,所以您可以使用这些值作为位掩码来识别资产
如果你不习惯二进制运算,你肯定会选择一个艰难的。
%d
是一个整数(PHAssetMediaSubtypePhotoPanorama
或PHAssetMediaSubtypeVideoHighFrameRate
的原始值),它将与媒体子类型的原始值相匹配,该原始值也是一个整数,但它是一个位掩码。因此,它可以表示多个值,这是有道理的,因为一块媒体可以同时具有多个子类型。
例如,值6(110
)表示4(100
)和2(10
)。所以我们不能用简单的平等来表达这一点。如果我们想要100
,我们想要任何设置该位的值,但我们不关心其他任何位:100
是匹配的,但110
也是匹配的,111
也是匹配的和101
也是匹配的。
在Swift中,我们可以将其分解为一个OptionSet,并对其执行逐集contains
。但在Objective-C中,这是谓词语言,你不能这样做。
因此,我们对100
的位进行逐位AND,从而将除一位之外的所有内容都更改为0
。例如,110 & 100
是100
,并且111
&100
是100
,依此类推。但010 & 100
是0
。好的,如果结果是而不是0
,那么我们的位就不是0
。因此是1
,我们有一场比赛。
为什么这都是基于camelbased的?
这就是目标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")
但我不明白怎么做。
这就是NSPredcate的工作原理。目标C具有高度的动态性和内省性,因此字符串可以表示属性的名称。阅读文档。https://developer.apple.com/documentation/foundation/nspredicate