我有以下 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 会因应用程序没有响应而终止该应用程序。奇怪。
现在,如果我将主体添加到循环中,就像这样:
for (length = 0; array[length] != nil; length++)
{
NSLog(@"%d",length);
}
然后它就可以正常工作了即使在发布模式下。
给循环一个空体,就像这样:
for (length = 0; array[length] != nil; length++){}
在释放模式下仍然冻结。
我的猜测是在发布模式下运行时有编译器优化,但到底是什么?!
有什么想法吗?
C 风格的数组默认不是以 nil 结尾的。如果你想通过这种方式检查长度,你需要自己添加终止符。
static NSString *const OrderByValueNames[] =
{@"None",@"Added",@"Views",@"Rating",@"ABC",@"Meta",nil};
找到长度的更好方法就是这样:
length = sizeof(OrderByValueNames) / sizeof(OrderByValueNames[0]);
(请注意,如果将数组传递给函数,则此技巧不起作用,因为它会退化为指针。)
您的
OrderByValueNames
数组不包含 nil
元素。难怪你找不到!像这样离开数组的末尾将导致未定义的行为。如果您想用 nil
标记数组的末尾,则必须手动添加。
顺便说一句,如果你想知道固定大小的 C 数组的长度,你可以这样做:
length = sizeof(OrderByValueNames)/sizeof(OrderByValueNames[0]);
但这不适用于函数参数,因为它们只是指针!