Objective c 斯普林泰诺词典

Objective c 斯普林泰诺词典,objective-c,nsmutabledictionary,Objective C,Nsmutabledictionary,我是objective-C的新手,我对它的语义很不熟悉。假设我有一堆存储在NSMutableDictionary中的SKSpriteNode,指向每个sprite代码的枚举状态: typedef enum PAWN_STATUS { OUT=0, MOVING, LANDED, IDLE } PAWN_STATUS; 然后 NSMutableDictionary* pawns = [[NSMutableDictionary alloc] init]; for(int i=0; i<10

我是objective-C的新手,我对它的语义很不熟悉。假设我有一堆存储在NSMutableDictionary中的SKSpriteNode,指向每个sprite代码的枚举状态:

typedef enum PAWN_STATUS { OUT=0, MOVING, LANDED, IDLE } PAWN_STATUS;
然后

NSMutableDictionary* pawns = [[NSMutableDictionary alloc] init];

for(int i=0; i<10; ++i) {
   SKSpriteNode *whiteButton = [SKSpriteNode spriteNodeWithImageNamed:@"white"];
   [pawns setObject:[NSNumber numberWithInt:OUT] forKey:whiteButton];
}

但最后一行不是更改现有SKSpriteNode的状态,而是添加一个新的SKSpriteNode。所以我的问题是为什么会这样?没有为节点定义散列?

我建议使用一种完全不同的方法来完成您试图完成的任务

您确实可以使用以下
SKNode
属性将用户数据与节点关联:

 @property(retain, nonatomic) NSMutableDictionary *userData
因此,您不需要处理自己的字典,将节点与其状态关联起来。您只需执行以下操作:

 touchedNode.userData = @{@"myNodeState":@LANDED};
     touchedNode.userData = @{@"myNodeState": kMyStateEnumLanded};
稍后,您将执行以下操作:

if ([touchedNode.userData[@"myNodeState"] intValue] == LANDED)
    ...
还请注意,使用“现代”Objective-C语法使其更简单

另一个与可读性无关的改进是使用
static const*NSString
而不是状态的枚举:

在.h文件中:

typedef NSString* MyStateEnums;
const MyStateEnums MyStateEnumLanded;
在.m文件中:

const MyStateEnums kMyStateEnumLanded = @"landedNodeState";
所以你可以做:

 touchedNode.userData = @{@"myNodeState":@LANDED};
     touchedNode.userData = @{@"myNodeState": kMyStateEnumLanded};
更重要的是:

if (touchedNode.userData[@"myNodeState"] == kMyStateEnumLanded)
编辑:

为了检查NSDictionary是否与SKNodeSprite配合使用,请执行以下简单测试:

//-- your code:
NSMutableDictionary* pawns = [[NSMutableDictionary alloc] init];
for(int i=0; i<10; ++i) {
   SKSpriteNode *whiteButton = [SKSpriteNode spriteNodeWithImageNamed:@"white"];
   [pawns setObject:[NSNumber numberWithInt:OUT] forKey:whiteButton];
}
//-- testing:
for (SKSpriteNode* node in [pawns allKeys]) {
    [pawns setObject:[NSNumber numberWithInt:LANDED] forKey:node];
}
for (SKSpriteNode* node in [pawns allKeys]) {
    NSLog(@"Node %x state: %d", (int)node, [[pawns objectForKey:node] intValue]);
}
/--您的代码:
NSMutableDictionary*pawns=[[NSMutableDictionary alloc]init];

对于(int i=0;我在将键/值对象添加到字典中时,您没有将它们前后对齐吗?对不起,特洛伊木马,但您所说的前后对齐是什么意思?
floatingPawnButton
从何而来?它是否应该是
touchedNode
?您认为键就是值,值就是键。当然,您的精灵就是对象和数字是钥匙吗?您是否也可以添加一个
NSLog(@“pawns:%@”,pawns)
的结尾处,检查字典是否正确填充?和NSLog的
floatingPawnButton
手动检查它是否已经存在。当然,sergio我知道我可以这样做,谢谢。但这并不能解决为什么NSMutableDictionary添加新对象而不是修改现有对象的问题。是吗t因为SKSpriteNode没有定义散列值?我认为问题在于OPs代码中缺少MVC模式(在这种情况下,视图的一部分是精灵)。只需对实体的“状态”进行建模(在屏幕上使用精灵表示)是冰山一角,其他属性将需要建模。@JuanChô:不幸的是,我没有您的所有代码来检查问题所在。我建议您进行我添加到答案中的简单测试,并报告结果。@sergio您提供的代码正在大量生成节点9c68ea0状态:2(当然,节点值正在更改),但值正在正确更改。但您正在迭代键。使用
objectForKey:
迭代键与使用具有给定值的
objectForKey:
迭代键之间没有区别(或
setObject:forKey:
)唯一的区别是,在第一种情况下,我确信对象在字典中——在第二种情况下,我不在字典中,并且对象可能不在字典中——这似乎是您的情况,因此添加了它(预期)。