带有整数值的NSDictionary

Cal*_*YSR 19 int objective-c nsdictionary

我正在和怪物一起玩游戏.每个人都有一个统计数据列表,这些数据都将是整数.我可以将每个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;
}
Run Code Online (Sandbox Code Playgroud)

我想做的事

-(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);
}
Run Code Online (Sandbox Code Playgroud)

错误我得到了

Arithmetic on pointer to interface 'id', which is not a constant size in non-fragile ABI
Run Code Online (Sandbox Code Playgroud)

所以我觉得我遇到问题的原因是我得到一个从objectForKey而不是整数返回的对象.所以我尝试对我正在获取的对象执行intValue方法,但这给了我另一个错误,具体来说:

Assigning to 'readonly' return result of an objective-c message not allowed
Run Code Online (Sandbox Code Playgroud)

我不知道如何解决这个问题.有帮助吗?放弃将它们全部存储在一起的想法会更好吗?只为每个统计使用一个int属性?

tro*_*foe 58

  1. 您只能在Cocoa集合类中存储对象而不是基元,因此要存储使用NSNumber对象所需的数字.
  2. NSMutableDictionary如果您希望稍后更改内容,则需要使用.
  3. 您的呼叫dictionaryWithObjectsAndKeys将键和值反转.
  4. 您的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];
Run Code Online (Sandbox Code Playgroud)

为了更改创建新NSNumber对象所需的值,因为它们是不可变的,所以类似于:

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

如果你问我,那一切都很乏味; 必须有一个更简单的方法,例如如何创建一个Objective-C类来存储和操作这些东西?


Dan*_*n F 7

NSDictionary的商店NSObject*.为了使用整数值,你不幸需要使用类似的东西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;
}
Run Code Online (Sandbox Code Playgroud)

然后你必须将它们作为数字检索:

NSNumber *atk = [self.stats objectForKey:@"Attack"];
int iAtk = [atk intValue];
[self.stats setObject:[NSNumber numberWithInt:iAtk] forKey:@"Attack"];
Run Code Online (Sandbox Code Playgroud)

编辑

当然,为了做到这一点,self.stats需要成为一个NSMutableDictionary

  • `dictionaryWithObjectsAndKeys`中的值和键的顺序颠倒过来,并且不保留`stats`. (2认同)

Tal*_*tle 6

使用很好的语法糖调整@ trojanfoe对现代Objective-C的答案:

stats = [@{@"Attack"          : @0,
           @"Defense"         : @0,
           @"Special Attack"  : @0,
           @"Special Defense" : @0,
           @"HP"              : @0} mutableCopy];
Run Code Online (Sandbox Code Playgroud)

并更新一个值:

stats[@"Attack"] = @([stats[@"Attack"] intValue] + (level * 5));
Run Code Online (Sandbox Code Playgroud)