0

彼はそこにいます、私はファイルとフォルダを持つ単純なツリー構造を持っています. これは、仮想フォルダをダウンロードできるクライアント サーバー アプリケーションの一部です。とにかく、非同期プログラミングに ^blocks を使用するのが好きです。私は3つのURLを持っています.1つ目はフォルダの説明をダウンロードし、2つ目はファイルをダウンロードするためのもので、3つ目はフォルダの内容をダウンロードするためのものです. DSFolder はフォルダの説明であり、DSFile は DSFolder から継承し、ダウンロード結果の NSData フィールドを含みます。フォルダーのダウンロード コードは次のようになります。

- (void)loadFolderData:(DSFolder *)folder 
              finished:(void(^)(DSFolder *))finished 
                 error:(void(^)(NSError *))error {

    if (!folder) {
        return;
    }
    for (DSFolder* fileOrFolder in folder.children) {
        if ([fileOrFolder isFolder]) {
            [self loadFolderData:fileOrFolder
                        finished:^(DSFolder * folder) {

                        // *********************************
                        // Next folder level would be a copy
                        // of the whole for loop in here
                        // *********************************

                    } error:^(NSError * err) {
                        if (error) {
                            error(err);
                        }
                    }];
        } else {
            [self loadFile:fileOrFolder.name
                    folder:folder.name
                  finished:^(NSData * data) {
                      ((DSFile *) fileOrFolder).data = data;
                  } error:^(NSError * err) {
                      if (error) {
                          error(err);
                      }
                  }];
        }
    }
}

ループを数回コピーするだけでツリーレベルの深さを制限できますが、それは非常に醜いようです。この質問が妥当であることを願っています。

4

1 に答える 1

1

再帰はすでに「ループのコピー」を実行しています:

- (void)loadFolderData:(DSFolder *)folder 
              finished:(void(^)(DSFolder *))finished 
                 error:(void(^)(NSError *))error {

    if (!folder) {
        return;
    }
    for (DSFolder* fileOrFolder in folder.children) {
        if ([fileOrFolder isFolder]) {
            [self loadFolderData:fileOrFolder finished:nil error:error];
        } else {
            [self loadFile:fileOrFolder.name
                    folder:folder.name
                  finished:^(NSData * data) {
                      ((DSFile *) fileOrFolder).data = data;
                  } error:error];
        }
    }
}

-loadFile:finished:error:nil エラーブロックを正しく処理すると仮定しています。

その他のいくつかのこと:

  • [self loadFile:fileOrFolder.name folder:folder.name ...]a/b/cサブディレクトリがある場合、間違ったことをしているように見えcます。bb/c
  • errorエラーごとに呼び出されます。これはおそらくあなたが望むものではありません。また、エラーの原因となった負荷も返しません。
  • 単一のコールバックを持つ方がより正常void(^)(DSFolder*,NSError*)です。
  • finished未使用です。階層全体のロードが完了したときに呼び出されるように見えますが、これは少しトリッキーです。
于 2013-01-18T23:39:10.363 に答える