避免 Objective-C 中的异步代码嵌套块

2024-03-05

我的 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();
    }];
}

这减少了代码重复,但仍然很混乱且难以跟踪。它甚至会产生具有尴尬名称的方法,这些方法实际上只是这种特殊情况的辅助方法。

一定会有更好的办法。看起来很像同步编码,但它是异步的。上面的代码很难阅读,如果我想向流程中添加新的内容,这会很危险。

更好的解决方案的建议?像这样的东西吗?

- (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 个对象。但是有类似格式的东西吗?它非常干净且易于维护。


我想你已经发现了调度组!

有上千篇文章,没有必要在这里毫无意义地粘贴一些东西,

等待多个网络请求全部执行 - 包括它们的完成块 https://stackoverflow.com/questions/10643797

cheers!


在更简单的层面上,您正在寻找的可能只是简单的“突破代码”这是编写简单、整洁的代码的关键部分。请注意,这并不总是解决方案,但通常 - 而且,我也不是 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块中;如果是这样的话,你的想法有点错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

避免 Objective-C 中的异步代码嵌套块 的相关文章

随机推荐