Number and Value Programming Topics
这是一个关于C基本数值类型的封装类 NSValue及亲儿子NSNumber, NSDecimalNumber, 和隔壁NSnull的故事
官方原文链接:Number and Value Programming Topics
NSValue:
NSValue 可以用来装任何标量数值(如int, float, char, 指针, 结构体, object ids)让基本的数值类型可以被添加到Cocoa Foundation 框架中的集合或者数组里面去. NSValue 都是 immutable 的.
创建 NSValue 使用
NSValue *theValue = [NSValue valueWithBytes: &myRange objCType:@encode(NSRange)];
需要传递数值型变量的指针及其 encode 类型 ,其中那个"@encode"返回值参看这里
例子:
NSRange myRange = {4, 10}; NSValue *theValue = [NSValue valueWithBytes: &myRange objCType:@encode(NSRange)];
创建结构体的 NSValue:
//假设 ImaginaryNumber 已定义; typedef struct { float real; float imaginary; } ImaginaryNumber; ImaginaryNumber miNumber; miNumber.real = 1.1; miNumber.imaginary = 1.41; NSValue *miValue = [NSValue valueWithBytes: &miNumber withObjCType:@encode(ImaginaryNumber)]; ImaginaryNumber miNumber2; [miValue getValue:&miNumber2];
文中还特别举例说明了不要忘记是传指针而不是具体变量数值:
/* INCORRECT! */ char *myCString = "This is a string."; NSValue *theValue = [NSValue valueWithBytes:myCString withObjCType:@encode(char *)]; /* Correct. */ char *myCString = "This is a string."; NSValue *theValue = [NSValue valueWithBytes:&myCString withObjCType:@encode(char **)];
NSNumber:
可以用来装char, short int,int, NSInteger, long int, long long int, float, double, BOOL.
还夹带了很多简单好用的初始化方法,如:
NSInteger nine = 9; float ten = 10.0; NSNumber *nineFromInteger = [NSNumber alloc] initWithInteger:nine]; NSNumber *tenFromFloat = [NSNumber numberWithFloat:ten]; NSNumber *nineFromInteger = @9; NSNumber *tenFromFloat = @10.0; NSNumber *nineteenFromExpression = @(nine + ten);
提供 compare 方法:
NSComparisonResult comparison = [nineFromInteger compare:tenFromFloat]; // comparison = NSOrderedAscending float aFloat = [nineFromInteger floatValue]; // aFloat = 9.0 BOOL ok = [tenFromFloat boolValue]; // ok = YES
还有就是如果使用了不恰当的类型来保存数值的话将会出错:
NSNumber *bigNumber = @(FLT_MAX); NSInteger badInteger = [bigNumber integerValue]; NSLog(@"bigNumber: %@; badInteger: %d", bigNumber, badInteger); // output: "bigNumber: 3.402823e+38; badInteger: 0"
NSDecimalNumber
浮点类型,精度38位,取值大小10底-128到127
-NSDecimalNumberBehaviors protocol
这货是用来处理计算时候发生的逻辑错误的(例如除零)
一些计算方法
NSDecimalAdd NSDecimalCompact NSDecimalCompare NSDecimalCopy NSDecimalDivide NSDecimalIsNotANumber NSDecimalMultiply NSDecimalMultiplyByPowerOf10 NSDecimalNormalize NSDecimalPower NSDecimalRound NSDecimalString NSDecimalSubtract
PS: 如果不需要把浮点型当成 obj 处理的话最好还是用 C 原型就可以,速度更加快还比较方便.
NSNull
其实 NSNull 放在这里和前面的 NSValue 没有什么关系的, 不知道为啥就合并在一个 topic 里面了
NSValue 可以在不能使用 nil 的地方使用,例如 array 的元素:
NSNull *nullValue = [NSNull null]; NSArray *arrayWithNull = @[nullValue]; NSLog(@"arrayWithNull:%@",arrayWithNull); //output: 2015-06-08 17:05:45.081 XYZPersonTest[733:36678] arrayWithNull:("<null>")
NSNull 和 nil 语义上差不多但是实际上不对等:
id aValue = [arrayWithNull objectAtIndex:0]; if (aValue == nil){ NSLog(@"equals nil"); }else if (aValue == [NSNull null]){ NSLog(@"equals NSNull instance"); if ([aValue isEqual:nil]){ NSLog(@"isEqual:nil"); } } //output: 2015-06-08 17:11:35.376 XYZPersonTest[744:38324] equals NSNull instance