如何使用Objective-C中的块进行结构化编程

当使用返回块的方法时,它们可以非常方便.
但是,当你必须将它们中的几个字符串串起来时,它会很快地变得凌乱

例如,您必须连续调用4个URL:

[remoteapiWithURL:url1 success:^(int status){
    [remoteapiWithURL:url2 success:^(int status){
        [remoteapiWithURL:url3 success:^(int status){
            [remoteapiWithURL:url2 success:^(int status){
            //succes!!!
            }];
        }];
    }];
}];

所以对于每一次迭代,我深入一层,甚至我甚至不处理嵌套块中的错误.

当有一个实际循环时,它变得更糟.比方说,我想上传一个100块的文件

- (void) continueUploadWithBlockNr:(int)blockNr
{
    if(blocknr>=100) 
    {
    //success!!!
    }
    [remoteapiUploadFile:file withBlockNr:blockNr success:^(int status)
    {
        [self continueUploadWithBlockNr:blockNr];
    }];
}

这感觉非常不直观,非常不可读得非常快.

在.Net中,他们使用async和await关键字解决了所有这些,基本上将这些延续展开为一个看似同步的流程.

Objective C的最佳实践是什么?

解决方法

你的问题立即让我想起递归.原来,Objective-c blocks can be used in recursion.所以我想出了以下解决方案,这是很容易理解,可以扩展到N任务相当不错.
// __block declaration of the block makes it possible to call the block from within itself
__block void (^urlFetchBlock)();

// Neatly aggregate all the urls you wish to fetch
NSArray *urlArray = @[
    [NSURL URLWithString:@"http://www.google.com"],[NSURL URLWithString:@"http://www.stackoverflow.com"],[NSURL URLWithString:@"http://www.bing.com"],[NSURL URLWithString:@"http://www.apple.com"]
];
__block int urlIndex = 0;

// the 'recursive' block 
urlFetchBlock = [^void () {
    if (urlIndex < (int)[urlArray count]){
        [self remoteapiWithURL:[urlArray objectAtIndex:index] 
            success:^(int theStatus){
                urlIndex++;
                urlFetchBlock();
            }

            failure:^(){
                // handle error. 
            }];
    }
} copy];

// initiate the url requests
urlFetchBlock();

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...