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

时间:2010-10-29 00:25:22

标签: objective-c coding-style

我正在尝试编写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;
    }
}

2 个答案:

答案 0 :(得分:1)

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

[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数组。它应该比使用(和创建)对象更快。

答案 1 :(得分:1)

您应该注意的唯一问题是NSDictionary复制其密钥。因此,Body需要实现NSCopyingBodytotals的实例不一定是传入bodies数组中的相同实例,具体取决于您的实现方式NSCopying。

我将使用的方法是将速度视为身体的属性。这样你就不需要字典来将主体与其速度相关联,你可以只遍历数组本身。


谈论迭代。您可以通过与第一个体同时计算另一个体的速度,将迭代次数和一些计算减半。即你的内部循环只会遍历数组中外部循环体之后的实体。

这意味着您无法使用快速迭代,因此您必须进行分析以确定哪种方法更快。


小调,我想

 for ....
 {
     if (!condition)
     {
         continue;
     }
     // do stuff
 }

真的很难看。出了什么问题:

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