是(有可能):符合协议_ObjectiveCBridgeable
(以下答案基于使用斯威夫特2.2和 XCode 7.3。)
正当我思考是否要发布或干脆跳过这个问题时,我偶然发现swift/stdlib/public/core/BridgeObjectiveC.swift https://github.com/apple/swift/blob/master/stdlib/public/core/BridgeObjectiveC.swift在 Swift 源代码中,特别是协议_ObjectiveCBridgeable
。我之前曾短暂注意到该协议Swiftdoc.org http://swiftdoc.org/v2.1/protocol/_ObjectiveCBridgeable/,但在后者目前的(空)蓝图形式中,我从未对其进行过太多思考。使用蓝图_ObjectiveCBridgeable
然而,从 Swift 源代码中,我们可以迅速让一些自定义类型的本机符合它。
在继续之前,请注意_ObjectiveCBridgeable
是一个内部/隐藏协议(_UnderScorePreFixedProtocol
),因此基于它的解决方案可能会在即将推出的 Swift 版本中在没有警告的情况下崩溃。
启用Int64
衔接基础课程NSNumber
举个例子,扩展Int64
符合_ObjectiveCBridgeable
,然后测试这个非常简单的修复是否足以进行隐式类型转换(桥接)Int64
到基础班NSNumber
holds.
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:
/* 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
确实足以启用自动分配桥接到相应的基础类;在这种情况下,NSNumber
(在斯威夫特中,__NSCFNumber
).
启用Int8
, UInt8
, Int16
, UInt16
, Int32
, UInt32
, (Int64
), and UInt64
桥接到NSNumber
上述符合Int64
to _ObjectiveCBridgeable
可以轻松修改以覆盖任何 Swift 原生整数类型,使用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 */