Ну, я не беспокоили соответствие вашего облако закрытия скобки, но вот попробовать, просто используя возврат, который вы можете свободно использовать внутри блоков слишком и разрезает вложенности немного:
[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 или другие инструменты документации для каждого метода, а не надеяться понять беспорядок вложенных недокументированных блоков.
Это только сходит с ума, если вы позволите ему сойти с ума.
Я не совсем уверен, какого ответа вы ожидаете. Если вы хотите избежать блокировки, не пишите методы, которые принимают блоки. И даже если они вам нужны, как и для диспетчерской части, в этом нет ничего плохого. – NSAddict
@NSAddict Да. Возможно, я могу перепроектировать функции на уровне бизнес-логики, которые могли бы избежать блокировки ада. Но я все еще хочу знать, есть ли какие-то фреймворки или синтаксический сахар, которые могут выровнять эти асинхронные вызовы. – nickcheng
Вы можете переместить внутреннюю часть каждого блока в отдельный метод, чтобы избежать глубокого (оптического) вложения. –