NSNumber
Int32
UInt32
Int64
UInt64
这种解决方案的预期用法示例:
let foo : Int64 = 42 let bar : NSNumber = foo /* Currently, as expected, error: cannot convert value of type 'Int64' to specified type 'NSNumber */
一些本机Swift数(值)类型可以自动桥接到NSNumber(引用)类型:
迅数字结构类型的实例,例如Int,UInt, Float,Double,和Bool,不能由所表示的 AnyObject类型,因为AnyObject仅代表一个类类型的实例。但是,Foundation启用桥接到时,可以将Swift数值分配给常量和AnyObject类型变量, 作为 类的 桥接实例NSNumber。 … Swift会自动将某些本机数字类型(例如Int 和)桥Float接到NSNumber。通过这种桥接,您可以NSNumber从以下类型之一创建 : let n = 42 let m: NSNumber = n 它还允许您将类型的值传递Int给例如 期望为的参数NSNumber。… 以下所有类型都会自动桥接到NSNumber: - Int - UInt - Float - Double - Bool
迅数字结构类型的实例,例如Int,UInt, Float,Double,和Bool,不能由所表示的 AnyObject类型,因为AnyObject仅代表一个类类型的实例。但是,Foundation启用桥接到时,可以将Swift数值分配给常量和AnyObject类型变量, 作为 类的 桥接实例NSNumber。
Int
UInt
Float
Double
Bool
AnyObject
Foundation
…
Swift会自动将某些本机数字类型(例如Int 和)桥Float接到NSNumber。通过这种桥接,您可以NSNumber从以下类型之一创建 :
let n = 42 let m: NSNumber = n
它还允许您将类型的值传递Int给例如 期望为的参数NSNumber。…
以下所有类型都会自动桥接到NSNumber:
- Int - UInt - Float - Double - Bool
从互操作性出发-使用可可数据类型- 数字。
那么,为什么要尝试为IntXX/ UIntXX类型复制呢?
IntXX
UIntXX
主要是: 好奇心,这是由于最近看到一些问题而引起的,这些问题涉及一些困惑,这些困惑涵盖了为什么一个Int值类型似乎可以由一个AnyObject(引用)变量表示,而例如Int64,不能;这自然可以通过上面提到的桥接来解释。
上面的问答均未提及从非桥接类型实际实现到AnyObject(NSNumber)的这种自动桥接的可能性Int64,UInt16依此类推。这些线程中的答案(正确地)集中在解释为什么AnyObject不能保存值类型,以及如何不桥接IntXX/ UIntXX类型以将其自动转换为基础的基础Foundation类型。
UInt16
其次: 对于同时在32位和64位体系结构上运行的应用程序,存在一些狭窄的用例-AnyObject在某些情况下使用隐式转换为的Swift本机数字类型- 在使用egInt32或Int64type优先Int。一个(有点)这样的例子:
_ObjectiveCBridgeable
(以下答案基于使用 Swift 2.2 和XCode 7.3的情况。)
正如我在考虑是发布还是跳过该问题时,我偶然发现了swift/stdlib/public/core/BridgeObjectiveC.swiftSwift源代码,尤其是协议_ObjectiveCBridgeable。我之前在Swiftdoc.org上已经简短地注意到了该协议,但是在后者的当前(空)蓝图形式中,我从没有对此进行过多考虑。_ObjectiveCBridgeable但是,使用来自Swift来源的蓝图,我们可以迅速让一些自定义类型的本机遵循它。
swift/stdlib/public/core/BridgeObjectiveC.swift
在继续之前,请注意这_ObjectiveCBridgeable是一个内部/隐藏协议(_UnderScorePreFixedProtocol),因此在即将发布的Swift版本中,基于该协议的解决方案可能会在没有警告的情况下中断。
_UnderScorePreFixedProtocol
启用Int64桥接至基金会类NSNumber
作为一个示例,扩展Int64以符合_ObjectiveCBridgeable,然后测试此非常简单的修复程序是否足以将隐式类型转换(桥接)从Int64Foundation类NSNumber保留。
import Foundation extension Int64: _ObjectiveCBridgeable { public typealias _ObjectiveCType = NSNumber public static func _isBridgedToObjectiveC() -> Bool { return true } public static func _getObjectiveCType() -> Any.Type { return _ObjectiveCType.self } public func _bridgeToObjectiveC() -> _ObjectiveCType { return NSNumber(longLong: self) } public static func _forceBridgeFromObjectiveC(source: _ObjectiveCType, inout result: Int64?) { result = source.longLongValue } public static func _conditionallyBridgeFromObjectiveC(source: _ObjectiveCType, inout result: Int64?) -> Bool { self._forceBridgeFromObjectiveC(source, result: &result) return true } }
测试:
/* Test case: scalar */ let fooInt: Int = 42 let fooInt64: Int64 = 42 var fooAnyObj : AnyObject fooAnyObj = fooInt // OK, natively fooAnyObj = fooInt64 // OK! _ObjectiveCBridgeable conformance successful /* Test case: array */ let fooIntArr: [Int] = [42, 23] let fooInt64Arr: [Int64] = [42, 23] var fooAnyObjArr : [AnyObject] fooAnyObjArr = fooIntArr // OK, natively fooAnyObjArr = fooInt64Arr // OK! _ObjectiveCBridgeable conformance successful
因此,符合_ObjectiveCBridgeable确实足以使自动预分配桥接到相应的Foundation类。在这种情况下NSNumber(在Swift中__NSCFNumber)。
__NSCFNumber
启用Int8,UInt8,Int16,UInt16,Int32,UInt32,( Int64)和UInt64桥接NSNumber
Int8
UInt8
Int16
使用下面的转换表Int64,_ObjectiveCBridgeable可以轻松地修改to 的上述一致性,以涵盖任何Swiftn本地整数类型NSNumber。
/* NSNumber initializer: NSNumber native Swift type property -------------------------------- ----------------------------------- init(char: <Int8>) .charValue init(unsignedChar: <UInt8>) .unsignedCharValue init(short: <Int16>) .shortValue init(unsignedShort: <UInt16>) .unsignedShortValue init(int: <Int32>) .intValue init(unsignedInt: <UInt32>) .unsignedIntValue init(longLong: <Int64>) .longLongValue init(unsignedLongLong: <UInt64>) .unsignedLongLongValue */