【问题标题】:Swapping Pointers in Objective C在 Objective C 中交换指针
【发布时间】:2013-12-25 23:42:47
【问题描述】:

我的目标是按大小对极坐标形式的向量数组进行排序。我使用冒泡排序实现了这一点,将 PolarVectors 中的所有值一一交换:

- (void) sortVectorsByMagnitude: (PolarVector*)one and:(PolarVector*)two
{
if (one.magnitude < two.magnitude)
    {
    PolarVector *temp = [[PolarVector alloc] init];
    temp.magnitude = one.magnitude;
    temp.angle = one.angle;
    one.magnitude = two.magnitude;
    one.angle = two.angle;
    two.magnitude = temp.magnitude;
    two.angle = temp.angle;
    }
} 

这行得通,但看起来很乱而且冗长。我尝试了以下代码但没有成功。据我了解,我正在交换此函数的本地指针,而不是我的主向量指针。

- (void) sortVectorsByMagnitude: (PolarVector*)one and:(PolarVector*)two
{
    if (one.magnitude < two.magnitude)
    {
        PolarVector *temp = [[PolarVector alloc] init];
        temp = one;
        one = two;
        two = temp;
     }
}

我尝试如下实现这个解决方案Swapping pointers

- (void) sortVectorsByMagnitude: (PolarVector*)one and:(PolarVector*)two
{
    if (one.magnitude < two.magnitude)
    {
        PolarVector temp;
        temp = *one;
        *one = *two;
        *two = temp;
    }
}

这会产生错误:

PolarVector temp  "Interface type cannot be statically allocated"

temp = *one;      "Assigning to 'PolarVector *' from incompatible type 'PolarVector'

*two = temp;      "Assigning to 'PolarVector' from incompatible type 'PolarVector *'

非常感谢(我希望这不是重复的——我找不到任何关于 Objective C 的直接信息)

【问题讨论】:

  • 你需要sortVectorByMagnitude:and:的调用者可以看到交换的结果吗?
  • 这纯粹是浪费运动:` = [[PolarVector alloc] init];`。如果你要在下一行为你的临时指针赋值,那么创建一个新对象是没有意义的,你只会掉在地板上。
  • 您缺少的一点是,虽然您的第二个代码段在做正确的事情(除了虚假的 alloc/init),但更新的值永远不会反映给调用者。
  • rmaddy:是的,结果需要对调用者可见。
  • Hot Licks:是的,非常正确。我想我的做法完全错误。

标签: objective-c pointers swap bubble-sort


【解决方案1】:

我的目标是按大小对极坐标形式的向量数组进行排序

然后:

NSMutableArray *vectors = /// whatever

[vectors sortUsingComparator:^NSComparisonResult(id _1, id _2) {
    PolarVector *p1 = _1, *p2 = _2;
    return p1.magnitude < p2.magnitude ? -1 :
           p1.magnitude > p2.magnitude ? +1 :
           0;
}];

突然之间就不需要搞乱冒泡排序、手动交换和其他东西了。

【讨论】:

  • 你不能直接说^NSComparisonResult(PolarVector *p1, PolarVector *p2)吗?
  • @JesseRusak 我可以这么说,但如果我这样写,那么它将无法编译。
  • 它编译得很好并且不会对我产生任何警告(在 Xcode 5 中)。
  • @JesseRusak 这是个好消息;那么很明显,在 Objective-C 中已经对此进行了更改。我也不喜欢强制性的id,但上次我检查它时,兼容的块类型(即签名)是强制性的。
  • 它们仍然是强制性的,但“兼容”的定义已经扩展,幸运的是,允许您使用更具体的类型而不是 id