如何在 Swift 中初始化一个 ALAssetsGroupType 常量?

How to initialize a ALAssetsGroupType constant in Swift?

我正在尝试初始化 Swift 中的 ALAssetsGroupType 常量(Xcode 6.4。):

let groupTypes: ALAssetsGroupType = ALAssetsGroupType(ALAssetsGroupAll)

但它不能为 32 位设备编译(例如,iPhone 5),我收到错误消息:

可能有更好的方法,但直接的方法是使用 Int32 的构造函数从 UInt32:

创建一个带符号的 Int32
let groupTypes: ALAssetsGroupType = ALAssetsGroupType(Int32(bitPattern: ALAssetsGroupAll))

说明

如果您选择单击 ALAssetsGroupType,您将看到它是 Int 的类型别名:

typealias ALAssetsGroupType = Int

但是,如果您随后单击 Declared In 旁边的 AssetsLibrary,您将在头文件中看到它实际上是 NSUInteger 的 typedef :

ALAssetsLibrary.h

typedef NSUInteger ALAssetsGroupType;

那么,这是怎么回事?为什么 Swift 不将 NSUInteger 视为 UInt? Swift 是一种强类型语言,这意味着您不能在不进行转换的情况下将 Int 分配给 UInt。为了让我们的生活更简单并消除其中的许多转换,Swift 工程师决定将 NSUInteger 视为 Int,这在大多数情况下省去了很多麻烦 .

下一个谜团是ALAssetsGroupAll的定义:

enum {
    ALAssetsGroupLibrary        = (1 << 0),         // The Library group that includes all assets.
    ALAssetsGroupAlbum          = (1 << 1),         // All the albums synced from iTunes or created on the device.
    ALAssetsGroupEvent          = (1 << 2),         // All the events synced from iTunes.
    ALAssetsGroupFaces          = (1 << 3),         // All the faces albums synced from iTunes.
    ALAssetsGroupSavedPhotos    = (1 << 4),         // The Saved Photos album.
#if __IPHONE_5_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED
    ALAssetsGroupPhotoStream    = (1 << 5),         // The PhotoStream album.
#endif
    ALAssetsGroupAll            = 0xFFFFFFFF,       // The same as ORing together all the available group types,
};

请注意 ALAssetsGroupAll 旁边的评论说 "The same as ORing together all the available group types"。好吧,0x3F 就足够了,但大概作者决定设置 所有 位只是为了将来证明它以防将来添加其他选项。

问题是,虽然 0xFFFFFFFF 适合 NSUInteger,但它不适合 Int32,因此您在 32 位系统上会收到溢出警告。上面提供的解决方案将 UInt32 0xFFFFFFFF 转换为具有相同 bitPattern 的 Int32。然后将其转换为 ALAssetsGroupType,它只是一个 Int,因此在 32 位系统上,您会得到一个 Int,所有位都已设置(这是 [=42= 的表示形式) ]).在 64 位系统上,-1Int32 值在 64 位中被符号扩展为 -1,这设置了该值的所有 64 位。

另一种解决方法是定义你自己的 AllGroups:

let AllGroups = -1  // all bits set
let groupTypes: ALAssetsGroupType = AllGroups

注意,这在 iOS 9 中已弃用:

typedef NSUInteger ALAssetsGroupType NS_DEPRECATED_IOS(4_0, 9_0, "Use PHAssetCollectionType and PHAssetCollectionSubtype in the Photos framework instead");