Проблема Objective-c с суммированием массива путем его перебора

У меня есть этот код, который принимает массив объектов дохода от 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);
}

Но строка NSLog(@"%@", total); вызывает ошибку EXEC BAD ACCESS. Есть ли что-то очевидное, что я сделал неправильно. Кроме того, если я удаляю журнал, ничего не добавляется к totalIncomes, который объявлен в моем заголовочном файле как NSNumber. Спасибо.


person Bodar    schedule 02.03.2011    source источник


Ответы (6)


Как насчет этого:

- (void)totalIncome:(NSMutableArray *)IncomesArray {
    NSNumber *total = [IncomesArray valueForKeyPath:@"@sum.value"];
    NSLog(@"total: %@", total);
}
person Dave DeLong    schedule 02.03.2011
comment
Он заявил, что объекты пришли из CoreData, не так ли? Очень хорошо. - person John Lemberger; 03.03.2011
comment
@JohnLemberger: да, хотя это не обязательно. это будет работать до тех пор, пока все объекты в массиве имеют метод -value, будь то NSObjects или NSManagedObjects. - person Dave DeLong; 03.03.2011

итог - это целое число. используйте 1_

другая вещь, которую вы должны сделать, это инициализировать вашу общую сумму до 0 в самом начале. В C (и Objective C) встроенные типы не обнуляются для вас. Это, вероятно, влияет на вашу общую сумму.

int total = 0;

Изменить: некоторые другие ответы предлагают вместо этого использовать %i. %i и %d эквивалентны для форматирования строки, как и %D. Вот полная таблица спецификаторов формата:

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

person TomSwift    schedule 02.03.2011
comment
Спасибо, Марк, две суммы в массиве — 56 и 22,3, сумма в self.totalIncomes — 105015200. Не знаю, почему? - person Bodar; 03.03.2011
comment
Том, спасибо за ваш ответ, который был блестящим. У меня недостаточно баллов, чтобы проголосовать, видимо. - person Bodar; 03.03.2011
comment
Так же разобрался с ошибкой. Дело в том, что поле в основных данных является числом с плавающей запятой, поэтому мне нужно рассматривать все как число с плавающей запятой. Я опубликую код. Спасибо за вашу помощь и быстрые ответы. - person Bodar; 03.03.2011

Вы используете '%@', который является форматом, используемым для строк. Вам нужно использовать '%i' для целых чисел. Пример:

NSLog(@"%i", total);
person FreeAsInBeer    schedule 02.03.2011
comment
Это гениально, спасибо. Знаете, почему сумма не складывается? - person Bodar; 03.03.2011
comment
Я заметил, что вы используете ++i в цикле for, что сделает i равным единице на первой итерации цикла. Вам нужно изменить это на i++, чтобы значение в первом индексе добавлялось правильно. - person FreeAsInBeer; 03.03.2011
comment
Спасибо, я только что спросил Марка выше об этом, но две суммы в массиве — 56 и 22,3, сумма в self.totalIncomes — 105015200. Я не знаю, почему? - person Bodar; 03.03.2011
comment
%@ не только для NSString. Это для любого объекта target-c, который поддерживает «описание» или «descriptionWithLocale:» - person TomSwift; 03.03.2011

- (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]);
}

Еще раз всем спасибо за помощь и быстрые ответы. Все мои ошибки были связаны с непониманием важности использования правильных типов данных во все времена.

person Bodar    schedule 02.03.2011
comment
В приведенном выше коде все еще есть по крайней мере две потенциальные проблемы: 1. self.totalIncomes может быть сохранен дважды и может произойти утечка. 2. Если «Доходы» означают валюту, то числа с плавающей запятой могут вызывать ошибки при суммировании в цикле. - person John Lemberger; 03.03.2011
comment
Спасибо, Джон, я попробую ваше решение для зацикливания. Должен ли я использовать двойную валюту? - person Bodar; 03.03.2011
comment
См. stackoverflow.com/questions/3730019/ - person John Lemberger; 03.03.2011
comment
Кроме того, Джонн, есть ли в вашем коде какое-либо освобождение объектов, которое мне нужно сделать вне метода Dealloc? - person Bodar; 03.03.2011

Как насчет:

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);
person John Lemberger    schedule 02.03.2011

Предлагается переписать:

- (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]);
}
person Hack Saw    schedule 03.03.2011