避免了在Objective-C异步code嵌套块 [英] Avoiding nested blocks with asynchronous code in objective-c

查看:120
本文介绍了避免了在Objective-C异步code嵌套块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很长的一系列事件,需要在我的Objective-C code发生。可以说我有6件事 - thingA,thingB,thingC,thingD,thingE和thingF。 thingB和thingD返回一个BOOL。如果thingB为否,则thingC不需要被调用。如果thingD为否,则thingE不需要被调用。

I have a long series of events that needs to happen in my Objective-C code. Lets say I have 6 things - thingA, thingB, thingC, thingD, thingE and thingF. thingB and thingD return a BOOL. If thingB is NO, then thingC doesn't need to be called. If thingD is NO, then thingE doesn't need to be called.

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

这很快就会变得非常笨重。你可以采取有不同的结果,但导致回圈的事情,使他们成为新的方法,因为这样的:

This can quickly become unwieldy. You can take the things that have different outcomes but lead back into the loop, and make them into new methods, as such:

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

这降低了code复制,但仍是混乱和难以跟踪。它甚至会导致与尴尬的名字,这是真的只是辅助方法,以这种特殊情况下的方法。

This reduces code duplication, but is still messy and difficult to keep track of. It even results in methods with awkward names, which are really just helper methods to this particular case.

必须有一个更好的办法。一些看起来很像同步编码,但是是异步的。以上code是难以阅读,这使得它危险的,如果我曾经想要新的东西加入到流程。

There must be a better way. Something that looks a lot like synchronous coding, but is asynchronous. The above code is difficult to read, which makes it dangerous if I ever want to add something new to the flow.

一个更好的解决方案的建议?像这样的事情?

Suggestions of a better solution? Something like this?

- (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对象。但一些与格式与此类似?它是如此更清洁,易于维护。

The immediately evident problem with that proposed solution is that the completion handler can pass out multiple objects, whereas the return value of a block can only handle 1 object. But something with a format similar to this? It's so much cleaner and easy to maintain.

推荐答案

我想你已经发现的调度组

上面有1000篇,没必要无谓的东西贴在这里,

there are 1000s articles on them, no need to pointlessly paste something in here,

等到多个操作执行 - 包括完成块(AFNetworking)

干杯!

在一个简单的水平,则可能是您要寻找的是只是简单的分离code这是写作的一个重要组成部分,简单,整洁code。请注意,这并不总是解决方案,但往往 - 也是,我不是你问清楚100%。但是,在挣脱code你是这样的...

On a simpler level, it's possible what you're looking for is just simply "breakaway code" which is a critical part of writing, simply, tidy code. Note that this is not always the solution, but often - also, I'm not 100% clear on what you're asking. But in break away code you go like this ...

{
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;
}

下面是一个典型的例子。你经常会看到code这样的事情...

Here's a typical example. Often you will see code something like this...

-(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
        }
  }

您和我在一起?但它是更好的把它写这样的:

You with me? But it's much better to write it like this:

-(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
  }

有道理?

请注意,重要的是,在任何实际的项目它是关于文档不是code,这样你就可以正确地讨论并评论...

Note that critically, in any real project it's about the documentation not the code, so you can properly discuss and comment on that ...

-(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
  }

有道理吧?我希望与你问什么帮助。你要想想你知道周围的其他方式?

Makes sense right? I hope that helps with what you were asking. You have to think the "other way around" you know?

根据经验,可能的规则是,如果你曾经有一个条件,然后是的code很长的块 - 这有点不对。把它周围的其他方法,并有分离的条件。只有这样,拥有实际的相关code。从某种意义上说..从来没有把重要的code长板的,如果块内;你那种思维方式不对周围如果是这样。

A possible rule of thumb is if you ever have a condition and then a "very long block of code" - it's sort of wrong. Turn it around the other way and have breakaway conditions. Only then, have "the actual relevant code". In a sense .. never put a long slab of important code inside an if block; you're sort of thinking the wrong way around if so.

这篇关于避免了在Objective-C异步code嵌套块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆