dfr*_*fri 6 nsnumber swift swift2
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 */
Run Code Online (Sandbox Code Playgroud)
一些原生的Swift数(值)类型可以自动桥接到NSNumber(引用)类型:
迅数字结构类型的实例,例如
Int,UInt,Float,Double,和Bool,不能由来表示AnyObject类型,因为AnyObject仅代表一个类类型的实例.但是,Foundation启用桥接时,可以将Swift数值分配给常量和AnyObject类型的变量 作为类的桥接实例NSNumber....
雨燕自动填补某些本地号码类型,如
Int和Float,对NSNumber.此桥接允许您NSNumber从以下类型之一创建 :Run Code Online (Sandbox Code Playgroud)let n = 42 let m: NSNumber = n它还允许您将类型的值传递
Int给例如期望的参数NSNumber....以下所有类型都自动桥接到NSNumber:
Run Code Online (Sandbox Code Playgroud)- Int - UInt - Float - Double - Bool
那么为什么要尝试为IntXX/ UIntXXtypes 复制呢?
主要是:好奇心,最近看到一些问题引发的潜在问题,包括为什么Int价值类型似乎可以用AnyObject(参考)变量来表示的混淆,而例如Int64,不能; 这可以通过上面描述的桥接自然解释.选几个:
然而,上面提到的Q&A:没有提到从非桥接类型实际实现这种自动桥接到AnyObject(NSNumber)的可能性Int64,UInt16等等.这些线程中的答案非常集中(正确地)解释为什么AnyObject不能保存值类型,以及如何将IntXX/ UIntXX类型桥接为自动转换为前者的基础Foundation类型.
其次:对于在32位和64位体系结构中运行的应用程序,有一些狭隘的用例 - 使用Swift本机数字类型隐式转换为AnyObject,在某些上下文中 - 使用egInt32或Int64type将优先于Int.一个(有点)这样的例子:
dfr*_*fri 11
_ObjectiveCBridgeable(以下答案基于使用Swift 2.2和XCode 7.3.)
正如我在思考是否发布或只是跳过这个问题一样,我偶然发现了swift/stdlib/public/core/BridgeObjectiveC.swiftSwift源代码,特别是协议_ObjectiveCBridgeable.我之前在Swiftdoc.org上曾经简要地注意过这个协议,但是在后者的当前(空白)蓝图中,我从未考虑过它._ObjectiveCBridgeable但是,使用Swift源代码中的蓝图,我们可以迅速让一些自定义类型的本机符合它.
在继续之前,请注意这_ObjectiveCBridgeable是一个内部/隐藏协议(_UnderScorePreFixedProtocol),因此在即将推出的Swift版本中,基于它的解决方案可能会在没有警告的情况下中断.
启用Int64基础课程的桥接NSNumber
作为一个例子,扩展Int64以符合_ObjectiveCBridgeable,并随后测试这个非常简单的修复是否足以从隐式类型转换(桥接)Int64到基础类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
}
}
Run Code Online (Sandbox Code Playgroud)
测试:
/* 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
Run Code Online (Sandbox Code Playgroud)
因此,一致性_ObjectiveCBridgeable确实足以实现自动的分配桥接到相应的基础课程; 在这种情况下,NSNumber(在Swift中__NSCFNumber).
启用Int8,UInt8,Int16,UInt16,Int32,UInt32,( Int64)和UInt64桥接NSNumber
使用下面的转换表Int64,_ObjectiveCBridgeable可以轻松修改to 的上述一致性以涵盖任何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 */
Run Code Online (Sandbox Code Playgroud)