当前位置: 首页 > 面试题库 >

是否可以将(U)Int8 / 16/32/64类型的Swifts自动数值桥接到Foundation(NSNumber)?

子车俊材
2023-03-14
问题内容

  • 是否有可能重复雨燕数值桥接基金会:■ NSNumber引用类型,例如Int32UInt32Int64UInt64类型?具体来说,复制下面介绍的自动预分配桥接。

这种解决方案的预期用法示例:

let foo : Int64 = 42
let bar : NSNumber = foo
    /* Currently, as expected, error:
       cannot convert value of type 'Int64' to specified type 'NSNumber */

背景

一些本机Swift数(值)类型可以自动桥接到NSNumber(引用)类型:

迅数字结构类型的实例,例如IntUIntFloatDouble,和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

从互操作性出发-使用可可数据类型-
数字。

那么,为什么要尝试为IntXX/ UIntXX类型复制呢?

主要是:
好奇心,这是由于最近看到一些问题而引起的,这些问题涉及一些困惑,这些困惑涵盖了为什么一个Int值类型似乎可以由一个AnyObject(引用)变量表示,而例如Int64,不能;这自然可以通过上面提到的桥接来解释。

上面的问答均未提及从非桥接类型实际实现到AnyObjectNSNumber)的这种自动桥接的可能性Int64UInt16依此类推。这些线程中的答案(正确地)集中在解释为什么AnyObject不能保存值类型,以及如何不桥接IntXX/
UIntXX类型以将其自动转换为基础的基础Foundation类型。

其次:
对于同时在32位和64位体系结构上运行的应用html" target="_blank">程序,存在一些狭窄的用例-AnyObject在某些情况下使用隐式转换为的Swift本机数字类型-
在使用egInt32Int64type优先Int。一个(有点)这样的例子:


问题答案:

是(可能):通过遵守协议 _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,然后测试此非常简单的修复程序是否足以将隐式类型转换(桥接)从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)。

启用Int8UInt8Int16UInt16Int32UInt32,(
Int64)和UInt64桥接NSNumber

使用下面的转换表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              */


 类似资料:
  • 我正在与Keras/Tensorflow合作开发一种将部署到低端MCU的ANN。为此,我使用Tensorflow Lite提供的训练后量化机制对原始ANN进行量化。如果权重确实量化为int8,则偏差将从float转换为int32。考虑到我假装在CMSIS-NN中实现这个ANN,这是一个问题,因为它们只支持int8和int16数据。 是否可以将TF Lite配置为也将偏差量化为int8?下面是我正在

  • 我最近下载了12c oracle客户端64位(安装过程中包含ODBC驱动程序)。 之后,我打开了32位和64位的ODBC administrators,只有64位的ODBC administrators列出了Oracle驱动程序(添加新系统DSN时),这使我假设只包含64位Oracle驱动程序;但是,查看文件名。。。它被命名为SQORA32。DLL。这仍然是64位odbc驱动程序吗?我可以忽略这个

  • 问题内容: 我有一个32位.so二进制库,我必须生成使用它的64位程序。有没有办法包装或转换它,使其可以与64位程序一起使用? 问题答案: 不能。您不能直接链接到64位程序内部的32位代码。 最好的选择是编译一个可以在64位平台上运行的32位(独立)程序(使用ia32),然后使用一种进程间通信的形式从64位程序与其进行通信。

  • 使用getObject方法从ResultSet对象检索列时,该类由JDBC驱动程序选择。我正在寻找一种方法来选择在运行时检索列的类。 在下面的示例中,使用变量T作为整数创建类型Class1。 ResultSet类提供了一个名为getObject的方法,该方法接受列参数和类型映射参数。此类型映射仅用于UDT(用户定义的类型)。我需要这个功能应用到基本的SQL类型。我知道我可以使用switch/cas

  • 问题内容: 所以我有一些第三方的本机库只能在Windows,OSX,Linux的32位JVM中工作,我需要始终强制Java应用程序以32位JVM模式运行。 如果目标系统仅安装了64位JVM,该如何强制其以32位模式运行Java应用程序呢? 问题答案: 没有。 您指定的前提条件禁止该应用程序在32位JRE中运行(好的,我排除了bundle-the-JVM解决方案和install-the- JVM解决

  • 问题内容: 是否可以在Windows 7上同时安装32位和64位Java? 我有一些应用程序可以在64位下运行,但是有些应用程序只能在32位下运行。 问题答案: 是的,绝对没有问题。您甚至可以同时在同一台计算机上安装32位和64位Java的多个版本。 实际上,我本人也有这样的设置。