我想達到同樣的效果,但繼續使用塊來簡化我的代碼,而不是通過遞歸方法傳遞參數的麻煩。我想出了這個NSArray的類別:
NS_ASSUME_NONNULL_BEGIN
@interface NSArray(MH)
- (void)mh_asyncEnumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL* stop, dispatch_block_t next))block;
@end
NS_ASSUME_NONNULL_END
@implementation NSArray(MH)
- (void)mh_asyncEnumerateObjectsUsingBlock:(void (^)(id _Nonnull obj, NSUInteger idx, BOOL* stop, dispatch_block_t next))block{
__block NSUInteger index = 0;
__block BOOL stop = NO;
void (^next)();
__block __weak typeof(next) weakNext;
weakNext = next = ^void() {
void (^strongNext)() = weakNext;
// check if finished
if(stop || index == self.count){
return;
}
id obj = self[index];
index++;
block(obj, index - 1, &stop, strongNext);
};
next();
}
@end
它這樣使用:
NSArray* a = @[@"Malc", @"Bob", @"Jim"];
[a mh_asyncEnumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL *stop, dispatch_block_t next) {
// simulate an async network call
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@", obj);
next();
});
}];
輸出:
2016-01-04 22:41:04.631 Malc
2016-01-04 22:41:05.632 Bob
2016-01-04 22:41:06.720 Jim
正如你所看到的,這個演示的陣列中的每個字符串輸出1秒延遲。您可以在塊內進行網絡調用,然後在完成後再調用。如果您遇到錯誤並想取消設置,請按* stop = YES;在調用next()之前,和使用普通枚舉一樣。
NSArray *sites = [self.fetchedResultsController.fetchedObjects copy];
NSLog(@"sites - %@",sites);
[sites mh_asyncEnumerateObjectsUsingBlock:^(Site *site, NSUInteger idx, BOOL *stop, dispatch_block_t next){
NSLog(@"site name - %@,",site.name);
[[Wrapper sharedWrapper] sendRequestTo:site completionBlock:{
if(error){ // your completion block should have an error param!!!
*stop = YES;
}
NSLog(@"site name - %@",site.name);
next();
}];
}];
快速枚舉和枚舉使用塊是不一樣的。請發佈一些上下文的代碼,它會更容易幫助你 – Stavash
謝謝,現在編輯這個問題! – Devfly
異步網絡請求怎麼樣?他們在哪裏進來? – Stavash