对于(U)Int8 / 16/32/64类型,是否可以将Swifts自动数值桥接复制
题
>是否可以将Swifts数值桥接复制到Foundation:s 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(引用)类型:
从Interoperability – Working with Cocoa Data Types – Numbers起. 那么为什么要尝试为IntXX / UIntXX类型复制它呢? 主要是:通过最近看到一些问题引发的好奇心,这些问题包括为什么Int值类型看起来可以用AnyObject(引用)变量表示的混淆,而不是Int64,不能;这可以通过上面描述的桥接自然解释.选几个: > Why is a Swift Array<Int> compatible with AnyObject? 然而,上面提到的Q& A:中没有提到从非桥接类型Int64,UInt16等实际实现对AnyObject(NSNumber)的这种自动桥接的可能性.这些线程中的答案非常集中(正确地)解释为什么AnyObject不能保存值类型,以及IntXX / UIntXX类型如何不被桥接以自动转换为前者的基础Foundation类型. 其次:对于在32位和64位体系结构上运行的应用程序,有一些狭窄的用例 – 使用Swift本机数字类型隐式转换为AnyObject,在某些上下文中使用例如Int32或Int64类型优先于Int.一个(有点)这样的例子: > Why does this random function code crash on an iPhone 5 and 5S.
是(可能):符合协议_ObjectiveCBridgeable
(以下答案基于使用Swift 2.2和XCode 7.3.) 正如我在思考是否发布或只是跳过这个问题一样,我在Swift源代码中偶然发现了 在继续之前,请注意_ObjectiveCBridgeable是一个内部/隐藏协议(_UnderScorePreFixedProtocol),因此在即将推出的Swift版本中,基于它的解决方案可能会在没有警告的情况下中断. 启用Int64桥接到Foundation类NSNumber 作为示例,扩展Int64以符合_ObjectiveCBridgeable,并随后测试这个非常简单的修复是否足以从Int64到Foundation类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). 启用Int8,UInt8,Int16,UInt16,Int32,(Int64)和UInt64桥接到NSNumber 使用下面的NSNumber转换表,可以很容易地修改Int64到_ObjectiveCBridgeable的上述一致性,以涵盖任何Swift原生整数类型. /* 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 */ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |