他在那里,我有一个简单的树状结构,包含文件和文件夹。它是可以下载虚拟文件夹的客户端 - 服务器应用程序的一部分。无论如何我喜欢使用^块进行异步编程。我有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);
}
}];
}
}
}
我可以通过在几次内部复制循环来限制树级深度,但这看起来非常难看。我希望这个问题是合理的。
答案 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
未使用。看起来你希望在整个层次结构加载完成后调用它,这很轻松。