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

Posted

技术标签:

【中文标题】如何在 Swift 中初始化 ALAssetsGroupType 常量?【英文标题】:How to initialize a ALAssetsGroupType constant in Swift? 【发布时间】:2015-07-14 11:20:31 【问题描述】:

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

let groupTypes: ALAssetsGroupType = ALAssetsGroupType(ALAssetsGroupAll)

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

【问题讨论】:

【参考方案1】:

可能有更好的方法,但直接的方法是使用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(这是 -1 的表示形式)。在 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");

【讨论】:

如果您想知道“为什么”,我更新了答案并提供了解释?

以上是关于如何在 Swift 中初始化 ALAssetsGroupType 常量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift中初始化闭包变量?

如何在 swift 初始化程序中确定 Self 类

如何在 Swift 1.0 中覆盖 UIView 初始化程序

如何使用 Swift 在 SpriteKit 程序中初始化/移动相机?

如何在 Swift 1.2 中初始化自定义 UIView

如何在 iOS swift 中使用多个属性初始化 CBMutableCharacteristic