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 = 80
var 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!) ->Bool
func compare(_ aNumber: NSNumber!) ->NSComparisonResult
isEqualToNumber
只是比较是否相等,而compare
方法可以比较是否相等、大于和小于,它的返回值是NSComparisonResult
枚举类型。NSComparisonResult
枚举类型定义如下:
enum NSComparisonResult : Int {
case OrderedAscending //升序,前一个数比后一个数小
case OrderedSame //两个数相等
case OrderedDescending //降序,前一个数比后一个数大
}
下面看一个示例:
import Foundation
var intSwift = 89
var 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
类似。