NSDictionary с целыми значениями

Я работаю над игрой с монстрами. Каждый из них имеет список статистических данных, которые все будут ints. Я могу настроить каждый stat как свою собственную переменную, но я бы предпочел сохранить их в NSDictionary, так как они все связаны. У меня возникает проблема, когда я пытаюсь изменить значение каждого стата.

Что у меня:

-(id) init {
 self = [super init];
 if(self) {
 stats = [NSDictionary dictionaryWithObjectsAndKeys:
 @"Attack", 0,
 @"Defense", 0,
 @"Special Attack", 0,
 @"Special Defense", 0,
 @"HP", 0, nil];
 }
 return self;
}

Что я хочу сделать

-(void) levelUp {
 self.level++;
 [self.stats objectForKey:@"Attack"] += (level * 5);
 [self.stats objectForKey:@"Defense"] += (level * 5);
 [self.stats objectForKey:@"Special Attack"] += (level * 5);
 [self.stats objectForKey:@"Special Defense"] += (level * 5);
 [self.stats objectForKey:@"HP"] += (level * 5);
}

Ошибка, которую я получаю

Arithmetic on pointer to interface 'id', which is not a constant size in non-fragile ABI

Поэтому мне кажется очевидным, что причина, по которой я получаю проблему, заключается в том, что я получаю объект, возвращенный из objectForKey, вместо целого. Поэтому я попытался использовать метод intValue для объекта, который я получаю, но это дало мне еще одну ошибку, в частности:

Assigning to 'readonly' return result of an objective-c message not allowed

У меня нет идей, как это исправить. Любая помощь? Было бы лучше просто отказаться от идеи сохранить их все вместе и просто использовать свойство int для каждого стата?

3 ответа

  • Вы можете хранить объекты, а не примитивы, только в классах классов Cocoa, поэтому для хранения номеров необходимо использовать объекты NSNumber.
  • Вам нужно использовать NSMutableDictionary, если вы хотите изменить содержимое позже.
  • В вашем вызове dictionaryWithObjectsAndKeys есть ключи и значения отменены.
  • Ваш объект stats не сохраняется, поэтому он будет выпущен в следующий раз по циклу запуска (если вы используете ручной подсчет ссылок, то есть).

Вы хотите:

stats = [[NSMutableDictionary dictionaryWithObjectsAndKeys:
 [NSNumber numberWithInt:0], @"Attack",
 [NSNumber numberWithInt:0], @"Defense",
 [NSNumber numberWithInt:0], @"Special Attack",
 [NSNumber numberWithInt:0], @"Special Defense",
 [NSNumber numberWithInt:0], @"HP",
 nil] retain];

Чтобы изменить значения, вам нужно создать новый объект NSNumber, поскольку они неизменяемы, что-то вроде:

NSNumber *num = [stats objectForKey:@"Attack"];
NSNumber *newNum = [NSNumber numberWithInt:[num intValue] + (level * 5)];
[stats setObject:newNum forKey:@"Attack"];

Все довольно утомительно, если вы спросите меня; должен быть более простой способ, например, как создать класс Objective-C для хранения и управления этим материалом?


NSDictionary сохранить NSObject* s. Чтобы использовать их с целыми значениями, вам, к сожалению, нужно использовать что-то вроде NSNumber. Итак, ваша инициализация будет выглядеть так:

-(id) init {
 self = [super init];
 if(self) {
 stats = [NSDictionary dictionaryWithObjectsAndKeys:
 @"Attack", [NSNumber numberWithInt:0],
 @"Defense", [NSNumber numberWithInt:0],
 @"Special Attack", [NSNumber numberWithInt:0],
 @"Special Defense", [NSNumber numberWithInt:0],
 @"HP", [NSNumber numberWithInt:0], nil];
 }
 return self;
}

Затем вам нужно будет найти их как числа:

NSNumber *atk = [self.stats objectForKey:@"Attack"];
int iAtk = [atk intValue];
[self.stats setObject:[NSNumber numberWithInt:iAtk] forKey:@"Attack"];

ИЗМЕНИТЬ

Конечно, для этого self.stats должен быть NSMutableDictionary


Адаптация ответа @trojanfoe для современного Objective-C с приятным синтаксическим сахаром:

stats = [@{@"Attack" : @0,
 @"Defense" : @0,
 @"Special Attack" : @0,
 @"Special Defense" : @0,
 @"HP" : @0} mutableCopy];

И обновить значение:

stats[@"Attack"] = @([stats[@"Attack"] intValue] + (level * 5));

licensed under cc by-sa 3.0 with attribution.