19.1 数字类NSNumber
在Objective-C语言中有一些基本数据类型2:int、char、float和double,但是它们都不是类,不具有方法、成员变量和属性以及面向对象的特征。为了实现“一切都是对象”的承诺,因此在Foundation框架中使用NSNumber类来封装这些数字类型。这样数字就具有面向对象的基本特征了。
2基本数据类型int、char、float和double事实上是由C语言提供的,它们可以在C、C++和Objective-C中使用。
19.1.1 获得NSNumber实例
不仅是NSNumber类,Foundation框架中几乎所有的类,都有两种获得实例的方式:一种是通过构造器创建,另一种是通过工厂设计模式创建。
如图19-1所示,打开NSNumber的API帮助文档,单击菜单栏中的“显示目录”按钮,在页面的左边显示目录。其中以number开头的方法是静态工厂创建方法,它通过工厂设计模式创建NSNumber对象获得实例;而以init开头的方法构造器,则通过构造器创建NSNumber对象并初始化成员获得实例。

图 19-1 NSNumber API帮助文档
提示 静态工厂创建方法命名是有规律的,即把类名去掉NS前缀,小写后作为方法的开头,例如
NSString的静态工厂创建方法class func stringWithUTF8String(_ bytes: CString) -> Self!。该方法是通过一个UTF8字符串创建NSString字符串对象,它采用的命名方法是使用string开头。
下面看示例代码:
import Foundation ①var intSwift = 80var intNumber1 = NSNumber(integer: intSwift) ②var intNumber2 = NSNumber(int: CInt(intSwift)) ③var floatNumber1 = NSNumber(double: 80.00) ④let myint = intNumber1.intValue ⑤let myfloat = floatNumber1.floatValue ⑥
使用Foundation框架需要通过第①行的import Foundation语句引入框架。代码第②行、第③行和第④行使用NSNumber构造器创建对象,也就是NSNumber API中的init开头的方法构造器,例如我们打开NSNumber API中-initWithInteger:构造器,如图19-2所示,在Foundation框架中以init开头的方法构造器就是这样的,不同的语言语法表现形式不同。init(integer value: Int)构造器调用时就需要写成NSNumber(integer: intSwift)的形式,integer是外部参数名。

图 19-2 NSNumber API中-initWithInteger:构造器
代码第③行、第⑥行和第⑦行使用静态工厂创建对象。第⑧行和第⑨代码是调用属性获得基本数据类型数值。
第④行和第⑦行分别使用了CInt()和CDouble()函数,它们将数据类型转换为CInt和CDouble类型。在Swift中有一些数据类型与Objective-C类型中的基本数据类型相对应。表19-1是Objective-C基本数据类型和Swift类型对应关系表。
表19-1 类型对应关系
Objective-C类型
|
Swift类型
|
|---|---|
bool
|
CBool
|
char, signed char
|
CChar
|
unsigned char
|
CUnsignedChar
|
short
|
CShort
|
unsigned short
|
CUnsignedShort
|
int
|
CInt
|
unsigned int
|
CUnsignedInt
|
long
|
CLong
|
unsigned long
|
CUnsignedLong
|
long long
|
CLongLong
|
unsigned long long
|
CUnsignedLongLong
|
wchar_t
|
CWideChar
|
char16_t
|
CChar16
|
char32_t
|
CChar32
|
float
|
CFloat
|
double
|
CDouble
|
提示 Swift中的转换函数就是该类型加上括号,如
CInt类型的转换函数就是CInt()。
19.1.2 NSNumber对象的比较
数字的比较是非常常见的操作,那么在比较两个NSNumber对象大小的时候,可以转化成为基本数据类型比较,当然可以使用NSNumber的方法比较,这就是对象的优势了。
与比较相关方法有isEqualToNumber和compare,这两个方法的定义如下:
func isEqualToNumber(_ aNumber: NSNumber!) ->Boolfunc compare(_ aNumber: NSNumber!) ->NSComparisonResult
isEqualToNumber只是比较是否相等,而compare方法可以比较是否相等、大于和小于,它的返回值是NSComparisonResult枚举类型。NSComparisonResult枚举类型定义如下:
enum NSComparisonResult : Int {case OrderedAscending //升序,前一个数比后一个数小case OrderedSame //两个数相等case OrderedDescending //降序,前一个数比后一个数大}
下面看一个示例:
import Foundationvar intSwift = 89var intNumber = NSNumber(integer: intSwift)var floatNumber = NSNumber(double: 80.00)if intNumber.isEqualToNumber(floatNumber) == true {NSLog("相等")} else {NSLog("不相等")}switch intNumber.compare(floatNumber) {case.OrderedAscending:NSLog("第一个数小于第二个数")case .OrderedDescending:NSLog("第一个数大于第二个数")case .OrderedSame:NSLog("第一个数等于第二个数")}
输出结果如下:
2014-07-05 21:08:10.089 PlaygroundStub_OSX[7052:303] 不相等2014-07-05 21:08:10.092 PlaygroundStub_OSX[7052:303] 第一个数大于第二个数
上述代码比较简单,基本不需要解释,但是需要注意的是NSLog函数是Foundation框架中的函数,也可以在Swift中使用,它的用途是日志输出,与Swift的println类似。
