0

他在那里,我有一个带有文件和文件夹的简单树结构。它是可以下载虚拟文件夹的客户端-服务器应用程序的一部分。无论如何,我喜欢使用 ^blocks 进行异步编程。我有 3 个 url,第一个下载文件夹描述,第二个用于下载文件,第三个用于下载文件夹内容。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:正确处理一个零错误块。

其他几件事:

  • [self loadFile:fileOrFolder.name folder:folder.name ...]如果有子目录,它看起来会做错事:假设路径a/b/c的文件名是 ,c文件夹名是b,它看起来会加载b/c.
  • error每个错误都会调用。这可能不是你想要的。它也不会返回导致错误的负载。
  • 有一个回调更正常,例如void(^)(DSFolder*,NSError*).
  • finished未使用。看起来您希望在整个层次结构完成加载时调用它,这有点棘手。
于 2013-01-18T23:39:10.363 回答