当使用返回块的方法时,它们可以非常方便.
但是,当你必须将它们中的几个字符串串起来时,它会很快地变得凌乱
但是,当你必须将它们中的几个字符串串起来时,它会很快地变得凌乱
例如,您必须连续调用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();