带有整数值的NSDictionary

时间:2012-07-05 20:58:56

标签: objective-c int 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;
}

我想做什么

-(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 个答案:

答案 0 :(得分:57)

  1. 您只能在Cocoa集合类中存储对象而不是基元,因此要存储使用NSNumber个对象所需的数字。
  2. 如果您希望稍后更改内容,则需要使用NSMutableDictionary
  3. 您对dictionaryWithObjectsAndKeys的来电有关键和值已反转。
  4. 您的stats对象未被保留,因此下次运行循环时将会释放它(如果您正在使用手动引用计数,那就是)。
  5. 你想:

    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类来存储和操作这些东西?

答案 1 :(得分:7)

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

答案 2 :(得分:6)

使用漂亮的语法糖调整@ trojanfoe对现代Objective-C的回答:

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

更新值:

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