Ios 在objective-c中使用异步代码避免嵌套块
我的Objective-C代码中需要发生一系列事件。假设我有6样东西——A、B、C、D、F。thingB和thingD返回一个布尔值。如果thingB是NO,则不需要调用thingC。如果thingD是NO,则不需要调用thingEIos 在objective-c中使用异步代码避免嵌套块,ios,objective-c,asynchronous,objective-c-blocks,Ios,Objective C,Asynchronous,Objective C Blocks,我的Objective-C代码中需要发生一系列事件。假设我有6样东西——A、B、C、D、F。thingB和thingD返回一个布尔值。如果thingB是NO,则不需要调用thingC。如果thingD是NO,则不需要调用thingE - (void)doThings:(void(^)())completion { [self thingA: ^{ [self thingB: ^(BOOL success) { if (success) {
- (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();
}];
}
这减少了代码重复,但仍然很混乱,难以跟踪。它甚至会导致方法的名称很难理解,而这些方法实际上只是这种特殊情况下的辅助方法
一定有更好的办法。看起来很像同步编码,但却是异步的。上面的代码很难阅读,如果我想在流中添加新的内容,这就很危险了
更好的解决方案的建议?像这样的
- (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;
}
该解决方案的一个显而易见的问题是,完成处理程序可以传递多个对象,而块的返回值只能处理1个对象。但是类似于这种格式的东西?它非常干净,易于维护。我想你已经发现了调度组 上面有1000多篇文章,不需要在这里毫无意义地粘贴东西 干杯
在更简单的层面上,您可能只需要寻找“分离代码”,这是编写简单整洁的代码的关键部分。请注意,这并不总是解决方案,但通常-而且,我不是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)将名称加载到单元格中
{
如果(self.showname!=nil&&[self.showname notLike:@“blah”]&&Kount希望它能帮助您随意询问以下问题:问题是我的代码大部分是异步的。对调度组的快速测试表明,它根本不尊重当前线程之外的代码,这对我来说没有任何用处。除非我遗漏了什么?你知道,我强烈建议就此提出一个新问题,嘘举一个“异步调度组灾难”的例子——你知道,在这个问题上你不会有任何进展吗?
-(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
}