我正在尝试在
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旁边的注释表示“与将所有可用组类型进行ORing相同”.好吧,0x3F已经足够了,但可能是作者决定将所有的位设置为未来的证据,以防将来添加其他选项.
问题是虽然0xFFFFFFFF适合NSUInteger,但它不适合Int32,因此在32位系统上会出现溢出警告.上面提供的解决方案将UInt32 0xFFFFFFFF转换为具有相同bitPattern的Int32.然后转换为ALAssetsGroupType,它只是一个Int,所以在32位系统上,你得到一个设置了所有位的Int(代表-1).在64位系统上,Int32值-1在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");