2014-11-08 48 views
1

之前,我有一個適度的簡單的for循環看起來像這樣:等待在for循環回調Next循環

for (NSObject *obj in objectsArray) 
{ 
    [DoThingToObject:obj complete:^{ 
     //Do more 
    }]; 
} 

我需要做在我的陣列中的每個對象上的事情。但是,在我開始循環並在第二個對象上做一件事情之前,我需要等待第一個對象發生完成回調。

我該如何簡單地等待,然後做循環中的下一個對象?

謝謝。

回答

5

將是巨大的,如果目標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}]; 
} 
+0

OP是否需要最後提到的方法,我很想看到它的快速草圖。 – ravron 2014-11-08 23:58:56

+1

@Riley - 當然。請參閱編輯。 – danh 2014-11-09 01:05:41