2

我有以下 C 数组NSString *

static NSString *const OrderByValueNames[] = {@"None",@"Added",@"Views",@"Rating",@"ABC",@"Meta"};

现在,我想在运行时检查这个数组的长度,所以我写了以下方法:

NSInteger LengthOfArray(NSString *const array[])
{
    NSInteger length = 0;
    // For Loop Without a body!
    for (length = 0; array[length] != nil; length++);
    return length;
}

现在,当我在配置中运行此代码时debug,一切都很好,并且该函数返回了正确的结果。

但是,一旦我切换到release配置并再次运行它,程序就会在 for 循环中冻结。循环执行 10 秒后,iOS 会因应用程序没有响应而终止该应用程序。诡异的。

现在,如果我将 body 添加到循环中,就像这样:

for (length = 0; array[length] != nil; length++)
{
    NSLog(@"%d",length);
}

然后即使在发布模式下它也能正常工作。

给循环一个空的 body,就像这样:

for (length = 0; array[length] != nil; length++){}

仍然在释放模式下冻结。

我的猜测是在发布模式下运行时有编译器优化,但究竟是什么?!

有任何想法吗?

4

2 回答 2

10

默认情况下,C 风格的数组不是以 nil 结尾的。如果要这样检查长度,需要自己添加终结符。

static NSString *const OrderByValueNames[] =
   {@"None",@"Added",@"Views",@"Rating",@"ABC",@"Meta",nil};

找到长度的更好方法就是:

length = sizeof(OrderByValueNames) / sizeof(OrderByValueNames[0]);

(请注意,如果将数组传递给函数,则此技巧不起作用,因为它会退化为指针。)

于 2012-05-29T10:51:29.597 回答
6

您的OrderByValueNames数组不包含nil元素。难怪你找不到!像这样离开数组的末尾会导致未定义的行为。如果你想用 标记数组的结尾nil,你必须手动添加它。

顺便说一句,如果你想知道一个固定大小的 C 数组的长度,你可以这样做:

length = sizeof(OrderByValueNames)/sizeof(OrderByValueNames[0]);

但是,这不适用于函数参数,因为它们只是指针!

于 2012-05-29T10:52:18.707 回答