22

我正在做一个有怪物的游戏。每个都有一个统计数据列表,这些统计数据都将是整数。我可以将每个统计信息设置为它自己的变量,但我更愿意将它们保存在 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 属性的想法会更好吗?

4

3 回答 3

64
  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];

为了更改值,您需要创建一个新NSNumber对象,因为它们是不可变的,例如:

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

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

于 2012-07-05T21:10:39.493 回答
7

NSDictionaryNSObject*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

于 2012-07-05T21:03:05.543 回答
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));
于 2014-02-04T18:01:06.817 回答