1

私は次のコードを持っています:

__block NSDictionary *results;

if (username.length != 0 && password.length != 0) {
    NSMutableDictionary* params =[NSMutableDictionary dictionaryWithObjectsAndKeys:
                                  @"login", @"command",
                                  username, @"username",
                                  password, @"password",
                                  nil];

    [[API sharedInstance] commandWithParams:params onCompletion:^(NSDictionary *json) {
        for (id key in json) {

            NSLog(@"key: %@, value: %@", key, [json objectForKey:key]);
        }

        results = json;
    }];
}
for (id key in results) {

    NSLog(@"key: %@, value: %@", key, [results objectForKey:key]);

}

これは、私がいくつかのことを理解するために遊んでいるチュートリアルからのいくつかのコードです。チュートリアルでは、「完了時」の部分で多くのコードが実行されました。呼び出し元のコードが結果自体を処理できるように、NSDictionaryを返すようにします。

私が抱えている問題は、結果が設定されていないことです。最初のNSLogforループは出力を出力しますが、2番目のNSLogは出力を出力しません。私は何が欠けていますか?

4

3 に答える 3

2

非同期操作の理解が欠けています。完了ブロックは、開始した操作が完了するまで呼び出されません。[API sharedInstance]ただし、NSLog ステートメントは、メッセージが- に送信された直後に実行され、その時点でresultsは nil です。

于 2012-09-19T19:30:59.573 に答える
1

通常、完了ハンドラは非同期リクエストを示します。その場合、commandWithParams:onCompletion:メソッド内のコードは、その後のコードが実行されるときにまだ実行されていません。

したがって、結果オブジェクトを見ていますが、完了ハンドラーはまだ実行されていないため、値を設定していないため、まだ nil です。

于 2012-09-19T19:33:55.127 に答える
0

commandWithParams:onCompletion:問題は、メソッドが非同期である可能性が最も高いです。つまり、別のスレッドにディスパッチされます。

これはネットワーク呼び出しであると想定しますが、これはどの非同期メソッドにも当てはまります。基本的に、アプリがフリーズしないようにバックグラウンドでデータをダウンロードしています。

では、これはあなたのコードにとって何を意味するのでしょうか? そうですね、NSDictionary への初期化されていないポインターを作成します。次に、API クラスの共有インスタンスに、ネットワーク リクエストをディスパッチするように依頼します。次に、リクエストがディスパッチされた直後、おそらくネットワークリクエスト/長時間実行プロセスが終了する前に、次のコード行が実行されますが、これはたまたま for ループです。

于 2012-09-19T19:30:47.520 に答える