添加全部的简单方法NSNumber
数组中的 s 是(类似于@Mahonor 在评论中所说的):
NSArray *myArray = ... // array of NSNumber (or NSDecimalNumber) objects
NSNumber *sum = [myArray valueForKeyPath:@"@sum.self"];
与此相反集合运算符:sum状态,数组中的数字是not转换成double
,但要NSDecimal
。所以,没有精度损失当添加小数时。甚至NSNumber
非十进制数的对象将转换为NSDecimal
添加。求和的结果是一个实例NSDecimalValue
.
我用两种不同的方式验证(或尝试)这一点。首先,我运行了这段代码
NSNumber *a = [NSNumber numberWithDouble:1.2];
NSNumber *b = [NSDecimalNumber decimalNumberWithString:@"-5.7"];
NSArray *myArray = @[a, b];
id sum = [myArray valueForKeyPath:@"@sum.self"];
并通过设置环境变量“NSObjCMessageLoggingEnabled=YES”激活 Objective-C 消息日志记录。从创建的“/tmp/msgSends-NNNN”文件中可以看出,decimalNumber
(并不是doubleValue
) 被发送到两个数字对象。
其次,我创建了一个自定义类来实现decimalValue
and doubleValue
,并应用了@sum.self
自定义类的对象数组:
@interface MyClass : NSObject
@property (nonatomic, assign) double value;
@end
@implementation MyClass
- (NSDecimal)decimalValue
{
return [[NSNumber numberWithDouble:self.value] decimalValue];
}
- (double)doubleValue
{
return self.value;
}
@end
MyClass *a = [MyClass new]; a.value = 1.2;
MyClass *b = [MyClass new]; b.value = -5.7;
NSArray *myArray = @[a, b];
id sum = [myArray valueForKeyPath:@"@sum.self"];
通过在两种方法中设置断点,可以看出只有decimalValue
用于求和(并且valueForKeyPath:@"@sum.self"
如果类没有实现则抛出异常decimalValue
).
人们还可以看到decimalValue
被调用自
-[NSArray(NSKeyValueCoding) _sumForKeyPath:]
该方法的汇编代码表明NSDecimalAdd
用于将数字相加。