0

I have this code wich accepts an array of income objects from Core Data.

- (void)totalIncome:(NSMutableArray *)IncomesArray {
    int i;
    int total;
    for (i = 0; i < [IncomesArray count]; ++i)
    {
        Income *income = [IncomesArray objectAtIndex:i];

        total += (int)[income value];
        NSLog(@"%@", total);
    }
    self.totalIncomes = [[NSNumber alloc] initWithInt:(int)total];
    NSLog(@"%.2f", self.totalIncomes);
}

But the line NSLog(@"%@", total); causes an EXEC BAD ACCESS error. Is there something obvious I have done wrong. Also if I remove the log nothing is added to totalIncomes which is declared in my header file as a NSNumber. Thanks.

Bodar
  • 33
  • 7

6 Answers6

7

How about this:

- (void)totalIncome:(NSMutableArray *)IncomesArray {
    NSNumber *total = [IncomesArray valueForKeyPath:@"@sum.value"];
    NSLog(@"total: %@", total);
}
Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • He did state the objects came from CoreData didn't he. Very nice. – John Lemberger Mar 02 '11 at 21:55
  • 1
    @JohnLemberger: yep, though that's not a requirement. it'll work as long as all the objects in the array have a `-value` method, be they `NSObjects` or `NSManagedObjects`. – Dave DeLong Mar 02 '11 at 21:59
1

total is an int. use NSLog(@"%d", total);

the other thing you should be doing is initializing your total to 0 at the outset. In C (and Objective C) intrinsic types aren't zeroed out for you. This is probably affecting your total.

int total = 0;

Edit: some other answers suggest using %i instead. %i and %d are equivalent for string formatting, as is %D. Here's a complete chart of format specifiers:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html

TomSwift
  • 39,369
  • 12
  • 121
  • 149
  • Thanks Mark, the two totals in the array are 56 and 22.3, the total in self.totalIncomes is 105015200. I am not sure why? – Bodar Mar 02 '11 at 21:14
  • Tom, thanks for your answer that was brilliant. I don't have enough points to vote up apparently. – Bodar Mar 02 '11 at 21:22
  • Also I have figured the error out. It was that the field in core data is a float so I need to treat everything as a float. I will post the code. Thanks for all your help and fast responses. – Bodar Mar 02 '11 at 21:23
0

You are using '%@' which is the format used for strings. You need to use '%i' for integers. Example:

NSLog(@"%i", total);
FreeAsInBeer
  • 12,937
  • 5
  • 50
  • 82
  • That's brilliant thanks. Do you know why the total is not adding up? – Bodar Mar 02 '11 at 21:01
  • I noticed you are using `++i` in your for loop, which is going to make `i` equal to one on the first loop iteration. You need to cahge this to `i++` so that the value in the first index is added properly. – FreeAsInBeer Mar 02 '11 at 21:05
  • Thanks, I have just asked Mark above this as well but, the two totals in the array are 56 and 22.3, the total in self.totalIncomes is 105015200. I am not sure why? – Bodar Mar 02 '11 at 21:15
  • %@ is not just for NSString. It is for any objective-c object that supports 'description' or 'descriptionWithLocale:' – TomSwift Mar 02 '11 at 21:28
0

How about:

NSEnumerator *enumerator = [IncomesArray objectEnumerator];

int total = 0; 
Income *income;
while (income = [enumerator nextObject]) {
    total += [income intValue];
    NSLog(@"%d", total);    
}

self.totalIncomes = [NSNumber numberWithInt:total];
NSLog(@"%.2f", self.totalIncomes);
John Lemberger
  • 2,689
  • 26
  • 25
0
- (void)totalIncome:(NSMutableArray *)IncomesArray {
    int i;
    float total;
    for (i = 0; i < [IncomesArray count]; i++)
    {
        Income *income = [IncomesArray objectAtIndex:i];

        total += [[income value] floatValue];
        NSLog(@"%.2f", [[income value] floatValue]);
    }
    self.totalIncomes = [[NSNumber alloc] initWithFloat:(float)total];
    NSLog(@"%.2f", [self.totalIncomes floatValue]);
}

Thanks again for everyones help and fast responses. All my errors were due to my lack of understnding of the importance of using the correct data types at all times.

Bodar
  • 33
  • 7
  • There are still at least two potential problems in the code above: 1. self.totalIncomes could be retained twice and may leak. 2. If Incomes means currency then floats are likely to cause errors when summed in a loop. – John Lemberger Mar 02 '11 at 21:34
  • Thanks John, I will try your solution above for the looping. Should I use double for currency? – Bodar Mar 02 '11 at 21:43
  • See http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency – John Lemberger Mar 02 '11 at 21:52
  • Also Jonn, with your code are there any releasing of objects I need to do outside the dealloc method? – Bodar Mar 02 '11 at 21:56
0

A suggested rewrite:

- (void)totalIncome:(NSMutableArray *)IncomesArray {
    float total = 0; //automatics might not be initialized
    for (Income *income in IncomesArray) //use fast enumeration
    {
        total += [[income value] floatValue];
        NSLog(@"%.2f", [[income value] floatValue]);
    }
    //hand an autoreleased object to your setter:
    self.totalIncomes = [NSNumber numberWithFloat:(float)total]; 
    NSLog(@"%.2f", [self.totalIncomes floatValue]);
}
Hack Saw
  • 2,741
  • 1
  • 18
  • 33