Je travaille sur un jeu avec des monstres. Chacun a une liste de statistiques qui seront toutes des ints. Je peux configurer chaque statistique comme sa propre variable, mais je préfère les conserver dans un NSDictionary car elles sont toutes liées. Je rencontre un problème lorsque j'essaie de changer la valeur de chaque statistique.
Ce que j'ai:
-(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;
}
Ce que je veux faire
-(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);
}
Erreur que j'obtiens
Arithmetic on pointer to interface 'id', which is not a constant size in non-fragile ABI
Il me semble donc évident que la raison pour laquelle je rencontre le problème est que je reçois un objet renvoyé par objectForKey au lieu d'un entier. J'ai donc essayé de faire la méthode intValue sur l'objet que je reçois, mais cela m'a donné une autre erreur, en particulier:
Assigning to 'readonly' return result of an objective-c message not allowed
Je n'ai plus d'idées pour résoudre ce problème. De l'aide? Serait-il préférable de renoncer à l'idée de les stocker tous ensemble et d'utiliser simplement une propriété int pour chaque statistique?
NSNumber
.NSMutableDictionary
si vous souhaitez modifier le contenu ultérieurement.dictionaryWithObjectsAndKeys
a les clés et les valeurs inversées.stats
n'est pas conservé, il sera donc libéré la prochaine fois dans la boucle d'exécution (si vous utilisez le comptage manuel des références, c'est-à-dire).Tu veux:
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];
Afin de modifier les valeurs, vous devez créer un nouvel objet NSNumber
car elles sont immuables, donc quelque chose comme:
NSNumber *num = [stats objectForKey:@"Attack"];
NSNumber *newNum = [NSNumber numberWithInt:[num intValue] + (level * 5)];
[stats setObject:newNum forKey:@"Attack"];
Tout cela est assez fastidieux si vous me demandez; il doit y avoir un moyen plus simple, par exemple que diriez-vous de créer une classe Objective-C pour stocker et manipuler ce genre de choses?
NSDictionary
s store NSObject*
s. Pour les utiliser avec des valeurs entières, vous devez malheureusement utiliser quelque chose comme NSNumber
. Ainsi, votre initialisation ressemblerait à:
-(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;
}
Il vous faudrait ensuite les récupérer sous forme de nombres:
NSNumber *atk = [self.stats objectForKey:@"Attack"];
int iAtk = [atk intValue];
[self.stats setObject:[NSNumber numberWithInt:iAtk] forKey:@"Attack"];
MODIFIER
Bien sûr, pour ce faire, self.stats
doit être un NSMutableDictionary
Adapter la réponse de @ trojanfoe à l'Objective-C moderne avec du sucre de syntaxe Nice:
stats = [@{@"Attack" : @0,
@"Defense" : @0,
@"Special Attack" : @0,
@"Special Defense" : @0,
@"HP" : @0} mutableCopy];
Et pour mettre à jour une valeur:
stats[@"Attack"] = @([stats[@"Attack"] intValue] + (level * 5));