代码之家  ›  专栏  ›  技术社区  ›  FogleBird

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

  •  1
  • FogleBird  · 技术社区  · 14 年前

    我想写一个iPhone游戏。这个函数的作用是对几个物体施加引力。我将从python移植它,我想知道我使用字典和数组作为元组是否有意义,并且在目标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 回复  |  直到 14 年前
        1
  •  1
  •   JeremyP    14 年前

    你应该知道的唯一问题是 NSDictionary 复制其密钥。所以 Body 需要实施 NSCopying 以及 身体 在里面 totals 传入的实例不一定相同 bodies 数组取决于如何实现nscopying。

    我将使用的方法是将速度视为物体的一个属性。这样,你就不需要一个字典来把物体和它的速度联系起来,你只需要迭代数组本身。


    谈论迭代。你可以将迭代次数和一些计算减半,方法是在计算第一个物体的同时计算另一个物体的速度。也就是说,您的内部循环将只遍历数组中位于外部循环主体之后的主体。

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


    我想是小调的

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

    真的很难看。怎么了:

     for ....
     {
         if (condition)
         {
             // do stuff
         }
     }
    
        2
  •  1
  •   Benoît    14 年前

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

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