在objective-c中使用asynchronous代码避免嵌套块

我需要在我的Objective-C代码中发生很长的一系列事件。 假设我有6件东西 – thingA,thingB,thingC,thingD,thingE和thingF。 thingB和thingD返回一个BOOL。 如果thingB是NO,那么thingC不需要被调用。 如果thingD是NO,那么thingE不需要被调用。

- (void)doThings:(void(^)())completion { [self thingA: ^{ [self thingB: ^(BOOL success) { if (success) { [self thingC: ^{ [self thingD: ^(BOOL success) { if (thingD) { [self thingE: ^{ [self thingF]; completion(); }]; return; } [self thingF]; completion(); }]; }]; return; } [self thingD: ^(BOOL success) { if (success) { [self thingE: ^{ [self thingF]; completion(); }]; return; } [self thingF]; completion(); }]; }]; }]; } 

这可能很快变得笨拙。 你可以把那些有不同结果的东西带回到循环中,并把它们变成新的方法,例如:

 - (void)doThings:(void(^)())completion { [self thingA: ^{ [self attemptThingB: ^{ [self attemptThingD: ^{ [self thingF]; completion(); }] }]; }] } - (void)attemptThingB:(void(^)())completion { [self thingB: ^(BOOL success) { if (success) { [self thingC: { completion(); }]; return; } completion(); }]; } - (void)attemptThingD:(void(^)())completion { [self thingD: ^(BOOL success) { if (success) { [self thingE: ^{ completion(); }]; return; } completion(); }]; } 

这减less了代码重复,但是仍然是杂乱,难以追踪的。 它甚至导致名字尴尬的方法,对于这种特殊情况,这些方法实际上只是帮助方法。

一定会有更好的办法。 东西看起来很像同步编码,但是是asynchronous的。 上面的代码很难阅读,这使得如果我想添加一些新的stream程是危险的。

更好的解决scheme的build议? 像这样的东西?

 - (void)doThings { [self thingA]; BOOL thingBSuccess = [self thingB]; if (thingBSuccess == YES) { [self thingC]; } BOOL thingDSuccess = [self thingD]; if (thingDSuccess == YES) { [self thingE]; } [self thingF]; return; } 

提出的解决scheme的直接明显的问题是,完成处理程序可以传出多个对象,而块的返回值只能处理1个对象。 但有一个类似于这个格式的东西? 它非常清洁,易于维护。

我想你已经发现了派遣小组

上面有1000多篇文章,不需要在这里毫无意义的粘贴东西,

等到多个networking请求全部执行 – 包括它们的完成块

干杯!


在更简单的层面上,你所寻找的只是简单的“分离代码” ,这是写作的关键部分,简单而整齐的代码。 请注意,这并不总是解决scheme,但往往 – 我也不是100%清楚你要问什么。 但在分离代码你走这样…

 { do something; if ( failure, and you don't want to do any more ) return; do some other important thing; if ( failure of that thing, and you don't want to do any more ) return; do yet another routine here; if ( some other failed conditions, and you don't want to do any more ) return; } 

这是一个典型的例子。 通常你会看到这样的代码…

 -(void)loadNameInToTheCell { if ( self.showname != nil && [self.showname notLike:@"blah"] && kount<3 ) { // many many lines of code here // many many lines of code here // many many lines of code here } } 

你跟我? 但是这样写就好多了:

 -(void)loadNameInToTheCell { if ( self.showname == nil ) return; if ( [self.showname notLike:@"blah"] return; if ( kount<3 ) return; // many many lines of code here // many many lines of code here // many many lines of code here } 

说得通?

请注意,在任何真正的项目中,关键是文档而不是代码,所以你可以正确地讨论和评论这个…

 -(void)loadNameInToTheCell { if ( self.showname == nil ) return; // don't forget Steve's routine could return nil if ( [self.showname notLike:@"blah"] return; // should we worry about caps here? if ( kount<3 ) return; // client wants to change this to 4 in future - Steve // screw that ... Biff, 8/2014 // many many lines of code here // many many lines of code here // many many lines of code here } 

有意义吗? 我希望能帮助你提出的问题。 你必须考虑你知道的“其他方式”?

一个可能的经验法则是如果你有一个条件,然后是一个“非常长的代码块” – 这是错误的。 把它转向另一个方向,并有分离的条件。 只有这样,才有“实际的相关代码”。 从某种意义上说,从来没有在if块中放置一长串重要的代码; 如果是这样的话,你有点想错了。