Une façon simple d'ajouter tous les NSNumber
s dans un tableau est (semblable à ce que @Mahonor dit dans un commentaire):
NSArray *myArray = ... // array of NSNumber (or NSDecimalNumber) objects
NSNumber *sum = [myArray valueForKeyPath:@"@sum.self"];
Contrairement à ce que les États Collection Operators: sum, les chiffres du tableau pas converti en double
, mais en NSDecimal
. Par conséquent, aucune précision n'est perdue lors de l'ajout de nombres décimaux. Même les objets NSNumber
qui ne sont pas des nombres décimaux sont convertis en NSDecimal
pour l'addition. Le résultat de la sommation est une instance de NSDecimalValue
.
J'ai vérifié (ou essayé de le faire) de deux manières différentes. Tout d'abord, j'ai couru ce code
NSNumber *a = [NSNumber numberWithDouble:1.2];
NSNumber *b = [NSDecimalNumber decimalNumberWithString:@"-5.7"];
NSArray *myArray = @[a, b];
id sum = [myArray valueForKeyPath:@"@sum.self"];
et activé la journalisation des messages Objective-C en définissant la variable d'environnement "NSObjCMessageLoggingEnabled = OUI". Comme on peut le voir dans le fichier "/ tmp/msgSends-NNNN" créé, decimalNumber
(et non doubleValue
) est envoyé aux deux objets numériques.
Deuxièmement, je créé une classe personnalisée mise en œuvre à la fois decimalValue
et doubleValue
et appliqué @sum.self
à un tableau d'objets de la classe personnalisée:
@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"];
En définissant des points d'arrêt dans les deux méthodes, on voit que seulement decimalValue
est utilisé pour la sommation (et valueForKeyPath:@"@sum.self"
lève une exception si la classe n'implémente pas decimalValue
).
On peut aussi voir que decimalValue
est appelé à partir
-[NSArray(NSKeyValueCoding) _sumForKeyPath:]
et le code assembleur pour cette méthode montre que NSDecimalAdd
est utilise pour ajouter les numéros.
Si votre tableau contient des dictionnaires alors Apple fournit une seule ligne d'exécution NSNumber * amountSum = [YourArray valueForKeyPath: @ "@ sum.amount"]; NSLog (@ "% @", amountSum); –
pour plus d'informations, vous pouvez passer par ce lien http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueCoding/Articles/CollectionOperators.html –
@Manohar: Vous pouvez utiliser KVC également pour une plaine tableau: '[myArray valueForKeyPath: @" @ sum.self "]'. –