web-dev-qa-db-ja.com

整数値を持つNSDictionary

私はモンスターとのゲームに取り組んでいます。それぞれに、すべてintになる統計のリストがあります。各統計を独自の変数として設定できますが、それらはすべて関連しているため、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プロパティを使用するというアイデアを放棄する方が良いでしょうか?

19
CaldwellYSR
  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クラスを作成して、このようなものを保存および操作するにはどうでしょうか。

57
trojanfoe

NSDictionarysストア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"];

[〜#〜] edit [〜#〜]

もちろん、これを行うには、self.statsNSMutableDictionaryである必要があります

7
Dan F

Nice構文シュガーを使用した現代のObjective-Cに対する@trojanfoeの回答の適応:

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

値を更新するには:

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