將是巨大的,如果目標C有承諾,但在那之前,我通常處理這樣的事情遞歸,使用輸入數組作爲一個待辦事項列表...
- (void)doThingToArray:(NSArray *)array then:(void (^)(void))completion {
NSInteger count = array.count;
// bonus feature: this recursive method calls its block when all things are done
if (!count) return completion();
id firstThing = array[0];
// this is your original method here...
[self doThingToObject:firstThing complete:^{
NSArray *remainingThings = [array subarrayWithRange:NSMakeRange(1, count-1)];
[self doThingToArray:remainingThings then:completion];
}];
}
這工作正常短陣列。讓我知道如果數組很大(數千個元素),我可以告訴你如何以不會結束堆棧的方式進行遞歸(通過使doThing
方法採用單個參數並使用performSelector「遞歸」)。
編輯 - 執行選擇器讓當前運行循環完成並在下一次將選擇器排隊。這樣可以節省堆棧,因爲您在長陣列上遞歸,但只需要一個參數,所以我們必須通過整合陣列並將參數阻塞到單個集合對象中來使得該方法稍微不可讀...
- (void)doThingToArray2:(NSDictionary *)params {
NSArray *array = params[@"array"];
void (^completion)(void) = params[@"completion"];
NSInteger count = array.count;
// bonus feature: this recursive method calls its block when all things are done
if (!count) return completion();
id firstThing = array[0];
// this is your original method here...
[self doThingToObject:firstThing complete:^{
NSArray *remainingThings = [array subarrayWithRange:NSMakeRange(1, count-1)];
[self performSelector:@selector(doThingToArray2:)
withObject:@{@"array": remainingThings, @"completion": completion}
afterDelay:0];
}];
}
// call it like this:
NSArray *array = @[@1, @2, @3];
void (^completion)(void) = ^void(void) { NSLog(@"done"); };
[self doThingToArray2:@{@"array": array, @"completion": completion}];
// or wrap it in the original method, so callers don't have to fuss with the
// single dictionary param
- (void)doThingToArray:(NSArray *)array then:(void (^)(void))completion {
[self doThingToArray2:@{@"array": array, @"completion": completion}];
}
OP是否需要最後提到的方法,我很想看到它的快速草圖。 – ravron 2014-11-08 23:58:56
@Riley - 當然。請參閱編輯。 – danh 2014-11-09 01:05:41