iPhone递归完成块

时间:2013-01-18 23:15:39

标签: iphone networking recursion

他在那里,我有一个简单的树状结构,包含文件和文件夹。它是可以下载虚拟文件夹的客户端 - 服务器应用程序的一部分。无论如何我喜欢使用^块进行异步编程。我有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);
                      }
                  }];
        }
    }
}

我可以通过在几次内部复制循环来限制树级深度,但这看起来非常难看。我希望这个问题是合理的。

1 个答案:

答案 0 :(得分: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,文件夹名称为b,则会似乎加载b/c
  • error每个错误而被调用。这可能不是你想要的。它也不会返回导致错误的负载。
  • 单个回调更常见,例如void(^)(DSFolder*,NSError*)
  • finished未使用。看起来你希望在整个层次结构加载完成后调用它,这很轻松。