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は応答しないためにアプリを強制終了します。変。

さて、ループにボディを追加すると、次のようになります。

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

その後、リリースモードでも正常に動作します。

次のように、ループに空の本体を指定します。

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 に答える