4

私は持っている:

NSDictionary* server;

for (server in self.servers)
{
    if (<some criterium>)
    {
        break;
    }
}

// If the criterium was never true, I want to use the last item in the
// the array. But turns out that `server` is `nil`.

ループ ブロックは変更されませんserver

serverswith dictionaries でありNSMutableArray、ループ中に変更されないプロパティです。

ループが終了した後にserver値があるのはなぜですか?nil

ループ後にこのような変数を使用したのは初めてでした。あまり考えずに、(古い C 時代に)次のように動作すると想定しました。

int i;
for (i = 0; i < n; i++)
{
    ...
}
4

3 に答える 3

7

言語、ループが終了するとループ変数が nil に設定されることを定義します。言語は、ループ変数が最後の値を持つことを述べていません。まったく逆です。

舞台裏には、それには非常に正当な理由があります。高速反復では、基礎となるデータに関する仮定が作成されます。たとえば、可変配列を反復処理する場合、反復処理中に配列が変更されない場合があります。ループ変数を保持したり解放したりしないため、高速反復はとりわけ高速です。代わりに、基になるオブジェクト (配列など) に依存して参照を保持します。

しかし、ループが終了すると、その基礎となるオブジェクトは保証を提供しなくなります。配列がなくなるか、最後に使用された配列要素が削除される可能性があります。したがって、コンパイラは変数を保持するか、nil に設定する必要があります。nil に設定する方が高速です。

于 2016-07-18T21:36:10.297 に答える
5

a で使用される変数は、for-loop常にnilループの終了時に使用されます ( break@rmaddy が指摘するように、ステートメントでループが中断された場合を除く)。

誤解を避けるループの別の方法は次のとおりです。

for (NSDictionary* server in self.servers)
{
    //... server is not nil
}
//here server doesn't exist (out of scope)

ループ外の var に self.servers の値を保存する場合は、次のようにする必要があります。

NSDictionary* serverSave;

for (NSDictionary* server in self.servers)
{
    serverSave = server;
}
//here you can use serverSave, which will contain the last value of self.servers

お役に立てれば。

于 2016-07-18T20:23:24.293 に答える
-1

ARC を使用した Objective-C はそれを nil するため、ループの後は nil です ( Objective C の「for in」ループ後のループ変数の値を参照してください)。

したがって、次の最後に到達すると:

NSDictionary* server; // server is nil here

for (server in self.servers)
{
    ... // Does not set server to nil.
}

serverゼロになります。

特定の値を探している場合は、次のことができます。

NSDictionary *dict;

for (NSDictionary* server in self.servers)
{
    if (server == whatever you want){
        dict = server;
        break;
    }
}

または、最後の値を取得するには:

NSDictionary *dict;

for (NSDictionary* server in self.servers)
{
    dict = server;
}
于 2016-07-18T20:44:15.583 に答える