nic*_*eng 1 cocoa-touch objective-c grand-central-dispatch ios objective-c-blocks
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];
}
}];
}
}];
});
}
}];
});
}
}];
Run Code Online (Sandbox Code Playgroud)
疯?是.我遇到了这个麻烦.
有没有人有避免像这样的嵌套块的经验?
编辑:
多谢你们.确切地说,我们有更优雅的方法来做到这一点.如:
但我期望的是一般解决方案.也许是这样的:(下面的伪代码)
functionA.flat.success = [self functionB];
functionB.flat.isntnil = [self functionC];
functionB.flat.error = {};
functionC.flat.isntnil = [self functionD];
[flat call:functionA];
Run Code Online (Sandbox Code Playgroud)
好吧,我没有打扰匹配你的关闭括号的云,但这是一个尝试简单地使用返回,你可以在块内自由使用,并削减嵌套一点:
[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];
}];
}];
});
}];
});
}];
Run Code Online (Sandbox Code Playgroud)
此外,没有人强迫您内联编写块,您可以将它们声明为正常变量,然后再使用它们.事实上,如果你的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);
}
}
Run Code Online (Sandbox Code Playgroud)
每当我看到嵌套级别太高时,我将内部块作为常规方法放在类中,只需在块内调用它们即可.效果是一样的,但它看起来更干净,它允许您为每个方法使用appledoc或其他文档工具,而不是希望了解嵌套的未记录块的混乱.
如果你让它变得疯狂,它只会变得疯狂.
| 归档时间: |
|
| 查看次数: |
1595 次 |
| 最近记录: |