GCD和块非常好且方便。但是当我爱上它时,我发现发生了一些不好的事情。请看下面的这些代码:
[self functionA:^(BOOL success) {
if (success) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
[self functionB:^(NSError *error) {
if (error != nil) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self functionC:^(id result) {
if (result) {
[self functionD:^(BOOL success) {
if (success) {
[self DoSomething];
}
}];
}
}];
});
}
}];
});
}
}];
疯?是。我有麻烦了。
有人有避免像这样的嵌套块的经验吗?
编辑:
谢谢你们。确实,我们有更优雅的方法来做到这一点。如:
但是我期望的是一个通用的解决方案。可能是这样的:(下面的伪代码)
functionA.flat.success = [self functionB];
functionB.flat.isntnil = [self functionC];
functionB.flat.error = {};
functionC.flat.isntnil = [self functionD];
[flat call:functionA];
最佳答案
好吧,我没有麻烦匹配您的右括号,但是这里只是使用return的尝试,您也可以在块内自由使用并稍微减少嵌套:
[self functionA:^(BOOL success) {
if (!success)
return;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
[self functionB:^(NSError *error) {
if (!error)
return;
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self functionC:^(id result) {
if (!result)
return;
[self functionD:^(BOOL success) {
if (!success)
return;
[self DoSomething];
}];
}];
});
}];
});
}];
同样,没有人会强迫您内联编写块,您可以先将它们声明为普通变量,然后再使用它们。实际上,如果您的API对用户宽容,并且可以在不需要进行任何工作的情况下重复调用它们,则可以在可以重用它们之前先声明块:
- (void)foo:(Bar*)bar
{
// Prepare the success handler.
void (^successBlock)(Bar*) = ^(Bar *bar) {
[[NSNotificationCenter defaultCenter]
postNotificationName:@"barUpdated"
object:bar];
};
if (!bar.didAlreadyFetchStuff) {
[self wellYouBetterFetchSomething:bar withSuccess:successBlock];
} else {
// Oh, fake we already did the work.
successBlock(bar);
}
}
每当我看到嵌套级别过高时,我都会将内部块作为普通方法放入类中,并在内部将它们简单地调用。效果是一样的,但是看起来更加简洁,它允许您为每种方法使用appledoc或其他文档工具,而不必希望了解嵌套的未文档化块的混乱情况。
只有让它变得疯狂,它才会变得疯狂。
关于ios - 如何避免嵌套 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18311840/