Swift封装基本数值的NSNumber类
Swift封装基本数值的NSNumber类

Swift封装基本数值的NSNumber类

NSNumber 是 Swift 中 Foundation 框架提供的一个类,用于封装基本数值类型(如 Int、Float、Double、Bool 等),以提供一种统一的接口来处理不同类型的数值数据。它最早设计用于 Objective-C,但在 Swift 中仍然非常有用,尤其是在与动态类型或者 Cocoa 框架交互时。

基本特点

1、多类型支持

NSNumber 能封装几乎所有的基本数值类型,如 Int、Float、Double、Bool、UInt 等。

可以使用 NSNumber 的实例访问这些封装的值。

2、不可变

NSNumber 的实例是不可变的,意味着其值在创建后不能更改。

3、与 Objective-C 的桥接

在与 Objective-C 的 API 交互时,NSNumber 是一个关键的桥接类型,用于将数值类型转换为通用对象。

创建 NSNumber

1、使用基本数值类型

import Foundation

let numberFromInt = NSNumber(value: 42)       // Int
let numberFromDouble = NSNumber(value: 3.14) // Double
let numberFromBool = NSNumber(value: true)   // Bool

2、从字符串或其他输入创建

可以通过 NSDecimalNumber(NSNumber 的子类)从字符串构建精确的数值:

let decimalNumber = NSDecimalNumber(string: "123.456")
print(decimalNumber) // 输出 123.456

获取封装的值

NSNumber 提供方法将值提取为各种类型:

let number = NSNumber(value: 42.5)

let intValue = number.intValue         // 转为 Int,结果 42
let doubleValue = number.doubleValue   // 转为 Double,结果 42.5
let boolValue = number.boolValue       // 转为 Bool,非零值为 true

NSNumber 的用途

1、作为动态数值容器

可以在运行时决定存储哪种数值类型:

func printNumber(_ number: NSNumber) {
    print("Double: \(number.doubleValue), Int: \(number.intValue)")
}

printNumber(NSNumber(value: 42))     // 输出 Double: 42.0, Int: 42
printNumber(NSNumber(value: 3.14))  // 输出 Double: 3.14, Int: 3

2、与 Objective-C API 交互

在使用一些 Cocoa 框架(如 UserDefaults、Core Data、NotificationCenter)时,NSNumber 是常用类型:

let defaults = UserDefaults.standard
defaults.set(NSNumber(value: 42), forKey: "integerKey")

if let savedNumber = defaults.object(forKey: "integerKey") as? NSNumber {
    print(savedNumber.intValue) // 输出 42
}

3、存储混合数据类型

NSNumber 可以存储混合类型的数值在集合中:

let mixedArray: [NSNumber] = [
    NSNumber(value: 42),
    NSNumber(value: 3.14),
    NSNumber(value: true)
]

for number in mixedArray {
    print(number) // 输出 42, 3.14, 1
}

4、与动态类型的桥接

NSNumber 支持在 Swift 和 Objective-C 中动态检查类型:

let number = NSNumber(value: 42.5)
if let isInteger = number as? Int {
    print("It's an integer: \(isInteger)")
} else {
    print("Not an integer") // 会输出这句
}

注意事项

1、精度问题

尽量使用 NSDecimalNumber 处理高精度的数值计算。

将浮点类型提取为整数时会进行截断:

let number = NSNumber(value: 42.9)
print(number.intValue) // 输出 42

2、动态类型的风险

如果使用 NSNumber 包装动态类型,可能需要进行类型检查或转换,避免崩溃。

3、与 Swift 强类型的对比

Swift 本身的 Double、Int 等类型更高效、更安全。

NSNumber 适用于需要动态行为或与 Objective-C 桥接的场景。

总结

NSNumber 是一个灵活的工具,可以在动态环境中处理数值数据,同时也在与 Objective-C API 的交互中发挥重要作用。尽管 Swift 的类型系统更安全和强大,NSNumber 仍然是某些场景下的首选类型。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注