【问题标题】:Objective-C int is bridged as Int32 to SwiftObjective-C int 作为 Int32 桥接到 Swift
【发布时间】:2020-02-07 22:12:19
【问题描述】:

如果我是正确的,Objective-C 的int 类型长度取决于平台字长(即在 64 位环境中运行时为 64 位,在 32 位环境中运行时为 32 位)。

但是,在将 Objective-C 接口桥接到 Swift 时,此类型被桥接为 Int32,它明确定义了 32 位的大小。

这是一个错误,还是 Objective-C 中的 int 总是占用 32 位?如果不是错误,为什么会桥接为Int32

Objective-C 接口示例

-(int)numberOfItems;

桥接成:

func numberOfItems -> Int32

当我将方法签名更改为使用NSInteger 时,它会正确桥接:

-(NSInteger)numberOfItems;
func numberOfItems -> Int

如果我将 Objective-C 中的 int 更改为 NSInteger,或者这些类型在 Objective-C 中的行为方式完全相同,会有什么危险吗?

【问题讨论】:

  • Objective-C 通常不使用intunsigned int,它使用NSIntegerNSUInteger,所以采用第二种方式。 NSUInteger 也是正确的类型,因为您不能拥有负数的项目:)。
  • @trojanfoe 感谢您的评论。您能否详细说明“Objective-C 通常不使用 int 或 unsigned int” - 这些类型是否来自 C?我已经任意命名了这些方法,当然在这种情况下最好使用无符号整数。
  • @trojanfoe 你应该避免在这里使用NSUInteger。虽然不可能有负数的项目,但无符号数学非常容易出错,并且在 Swift 中桥接到UInt 非常不方便。在 ObjC 中 count 返回 NSUInteger 是一个错误,而在 Swift 中通过返回 Int 来修复该错误。
  • @RobNapier 同意你的观点,我实际上有一个错误,因为没有注意到返回的类型是NSUInteger:stackoverflow.com/questions/35265279/…
  • @RobNapier - 但我们已经偏离了最初的问题,我们应该等待类似“我应该使用无符号类型”之类的问题来讨论关于类型理论的观点!

标签: objective-c swift int nsinteger int32


【解决方案1】:

Objective C 的int(或者正确地说,Cint)应该是at least 16 bits in size,因此将其存储在 32 位中是无效的。 Probably in Apple's implementation it is always 32 bit for int.

如果我是正确的,Objective-C 的 int 类型长度取决于平台字长(即在 64 位环境中运行时为 64 位,在 32 位环境中运行时为 32 位)。

那将是NSInteger,而不是int。您可能会混淆它们,因为在Swift 中的IntObjective CNSInteger 的等效类型。

您甚至可以在文档中看到它:

typealias NSInteger = Int

【讨论】:

  • 谢谢,但是在生成 CoreData 类时,该类型是使用特定位数创建的(因为 CoreData 模型不允许选择与平台相关的选项),例如int32_t。这是否意味着 CoreData 使用 C 类型而不是 Objective-C?
  • 没错。 Core Data 将其整数的长度固定为特定的位宽,因为它们是持久存储的。否则,如果您在不同的架构上加载 Core Data 数据库,它就会损坏。
  • @RichardTopchiy CoreData 需要尽可能精确地指定位宽,所以它使用int<width>_t 类型。因为这些类型的大小必须完全为 width(而不是 at least that size widedepends on the platform wide)。
【解决方案2】:

Swift 不是从 generic (Objective-)C 而是从 Apple (Objective-)C 桥接的。在标准 C 中,int 的大小只有一个最小界限,而不是一个确切的大小。然而,Apple(和 GNU)编译器遵循特定的数据类型大小模型,来自 Apple 的 64-Bit Transition Guide

OS X 使用两种数据模型:ILP32(其中整数、长整数和指针是 32 位量)和 LP64(其中整数是 32 位量,长整数和指针是 64 位量) .其他类型等价于它们的 32 位对应物(除了 size_t 和一些基于长整数或指针的大小定义的其他类型)。

因此,在 ILP32(用于 32 位应用程序)和 LP64(64 位应用程序)中,int 的大小都是 32 位的。 Swift 中等价的整数类型是Int32

关于NSInteger 相同的参考声明:

除了对基本数据类型的这些更改之外,OS X 的各个层还具有其他数据类型,这些数据类型会在 64 位环境中更改大小或基础类型。这些变化中最值得注意的是 NSInteger 和 NSUInteger(Cocoa 数据类型)在 64 位环境中为 64 位,在 32 位环境中为 32 位。

Swift 的等价物是Int

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多