我在这里正确使用Objective-C集合了吗?

我在这里正确使用Objective-C集合了吗?,objective-c,coding-style,Objective C,Coding Style,我正在尝试写一个iPhone游戏。此功能旨在向多个对象应用重力。我正在从Python移植它,我想知道我使用字典和数组作为元组是否有意义,在Objective C中是否是典型的/惯用的。对代码的任何评论都值得赞赏 + (void)updateBodies:(NSMutableArray*)bodies { NSMutableDictionary* totals = [NSMutableDictionary dictionaryWithCapacity:[bodies count]];

我正在尝试写一个iPhone游戏。此功能旨在向多个对象应用重力。我正在从Python移植它,我想知道我使用字典和数组作为元组是否有意义,在Objective C中是否是典型的/惯用的。对代码的任何评论都值得赞赏

+ (void)updateBodies:(NSMutableArray*)bodies {
    NSMutableDictionary* totals = [NSMutableDictionary dictionaryWithCapacity:[bodies count]];
    for (Body* body in bodies) {
        if (body.fixed) {
            continue;
        }
        float tx;
        float ty;
        for (Body* other in bodies) {
            if (other == body) {
                continue;
            }
            float dx = other.x - body.x;
            float dy = other.y - body.y;
            float dist2 = pow(dx, 2) + pow(dy, 2);
            float dist = sqrt(dist2);
            float mass = pow(other.radius, 3);
            float magnitude = G * mass / dist2;
            float ux = dx / dist;
            float uy = dy / dist;
            tx += ux * magnitude;
            ty += uy * magnitude;
        }
        NSNumber* ntx = [NSNumber numberWithFloat:tx];
        NSNumber* nty = [NSNumber numberWithFloat:ty];
        NSArray* tuple = [NSArray arrayWithObjects:ntx, nty, nil];
        [totals setObject:tuple forKey:body];
    }
    for (Body* body in [totals allKeys]) {
        NSArray* tuple = [totals objectForKey:body];
        float tx = [[tuple objectAtIndex:0] floatValue];
        float ty = [[tuple objectAtIndex:1] floatValue];
        body.dx += tx;
        body.dy += ty;
    }
}

您可以使用块枚举进行最终更新:

[totals enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
  Body* body = key;
  NSArray* tuple = key;
  body.dx += [[tuple objectAtIndex:0] floatValue];
  body.dy += [[tuple objectAtIndex:1] floatValue];
}];

另一种解决方案是不使用NSDictionary和NSArray,而是使用C数组。它应该比使用(和创建)对象更快。

您应该注意的唯一问题是
NSDictionary
复制它的键。因此,
Body
需要实现
NSCopying
totals
中的
Body
实例在传入的
Body
数组中不一定是相同的实例,这取决于您实现NSCopying的方式

我将使用速度作为身体的属性。这样,您就不需要字典将实体与其速度相关联,只需迭代数组本身


说到迭代。通过在第一个实体的同时计算另一个实体的速度,可以将迭代次数和某些计算减半。i、 e.您的内部循环将只遍历数组中位于外部循环体之后的实体

这意味着您不能使用快速迭代,所以您必须分析以找出哪种方法更快


我想是一个小问题

 for ....
 {
     if (!condition)
     {
         continue;
     }
     // do stuff
 }
真的很难看。有什么问题吗

 for ....
 {
     if (condition)
     {
         // do stuff
     }
 }

他已经在使用快速枚举。这就是(…in…的
是什么。是的。。。我犯了一个错误。我想说块枚举是指没有一个callto-allKeys和objectForKey,这应该比块要昂贵。
continue
方法减少了嵌套。就像函数中的早期返回一样。谢谢,我最终发现了
NSCopying
问题。我改为使用NSMutableArray而不是NSMutableDictionary。@FogleBird:它并没有减少嵌套,只是掩盖了嵌套。@JeremyP:你对嵌套的定义是什么?这是
//dostuff
是一个缩进还是两个缩进之间的区别。@FogleBird:源代码的缩进应该反映其结构。我的两个例子的结构实际上是相同的,因为我们有一个嵌套在循环中的有条件执行的语句序列(do stuff部分),但在第二个例子中,缩进正确地反映了结构。我刚刚意识到我可以在第一个循环中更新
dx
dy
。出于某种原因,我认为我必须延迟更新它们,如果我正在更新
x
y
,这将是正确的。因此,现在这将变得简单得多,但这仍然是NS集合的良好实践。
for(Body*Body in[totals allkey])
可以写成
for(Body*Body in totals)