목표 -C에 약속을 추가하려는 공동체 시도가있을 수 있습니다. 여기에 필요한 것이기 때문에 좋을 것입니다. 완전히 새로운 라이브러리에 커밋하지 않고 비동기 작업을 재귀 적으로 수행하여 중첩을 처리 할 수 있습니다. 예를 들어 다음과 같습니다.
매개 변수가없는 작업부터 시작하십시오. 그리고 배열 결과 ...여기
- (void)firstOpWithCompletion:(void (^)(NSArray *, NSError *))completion {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSArray *components = [@"this is an array of strings from the FIRST op" componentsSeparatedByString:@" "];
if (completion) {
completion(components, nil);
}
});
}
내 대답에로 이전이
편집에, 이제 배열에 배열 PARAM을하고 결과를 몇 ...
- (void)secondOpWithParam:(NSArray *)array completion:(void (^)(NSArray *, NSError *))completion {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
if (completion) {
NSArray *components = [@"these strings are from the SECOND op" componentsSeparatedByString:@" "];
NSArray *result = [array arrayByAddingObjectsFromArray:components];
if (completion) {
completion(result, nil);
}
}
});
}
- (void)thirdOpWithParam:(NSArray *)array completion:(void (^)(NSArray *, NSError *))completion {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
if (completion) {
NSArray *components = [@"these strings are from the THIRD op" componentsSeparatedByString:@" "];
NSArray *result = [array arrayByAddingObjectsFromArray:components];
if (completion) {
NSLog(@"we did it. returning %@", result);
completion(result, nil);
}
}
});
}
// ...as many as these as you need
을, 우리는 단지 PARAM 패스를 추가 처음과 중간 통화에서 ...
- (void)doSeveralThingsInSequence:(NSArray *)todo param:(NSArray *)param {
if (todo.count == 0) return;
// you could generalize further here, by passing a "final" block and run that before the return
NSString *nextTodo = todo[0];
SEL sel = NSSelectorFromString(nextTodo);
IMP imp = [self methodForSelector:sel];
void (*func)(id, SEL, NSArray *, void (^)(NSArray *, NSError *)) = (void *)imp;
func(self, sel, param, ^(NSArray *result, NSError *error) {
if (!error) {
NSArray *remainingTodo = [todo subarrayWithRange:NSMakeRange(1, todo.count-1)];
[self doSeveralThingsInSequence:remainingTodo param:result];
}
});
}
는 코드를 통해 스테핑 :이 방법의 보석금을 아무 존재하지 않는 경우는, 그렇지 않으면 다음 선택 이름을 사용 전달 된 배열에서 C 함수 구현을 가져 와서 호출하고 나머지 선택자에 대해 프로세스를 시작하는 완료 블록을 호출 스택에 배치합니다.
마지막으로 doEverything은 시작하기 위해 첫 번째 연산을 호출 한 다음 배열 입력을 다음 배열 입력으로 전달하는 작업 목록 (임의로 긴 목록 일 수 있음)을 실행하기 시작합니다. (당신은 내가 정확히 게시 된이 테스트 예상 출력 본
- (void)doEverything {
[self firstOpWithCompletion:^(NSArray *array, NSError *error) {
NSArray *todo = @[ @"secondOpWithParam:completion:", @"thirdOpWithParam:completion:" ];
[self doSeveralThingsInSequence:todo param:array];
}];
}
더 체인을 따라 id
년대를 통과하여이를 일반화 수 : 내가 문제가되지한다고 생각합니다 그래서
(
this,
is,
an,
array,
of,
strings,
from,
the,
FIRST,
op,
these,
strings,
are,
from,
the,
SECOND,
op,
these,
strings,
are,
from,
the,
THIRD,
op
)
을하지만, 나는 그랜드 센트럴 디스패치로 충분히 확고하지 않다. 당신이했던 것처럼 당신은 블록을 체인에 넣을 수있다. 정확히 어디에서 싸우고 있는가? – Gulliva
나는 중첩하는 것이 가장 좋은 방법인지 잘 모르겠다. 작동하는 것은 의미하지만 읽고 유지하기가 어렵습니다. 대안이 있는지 확인하고 싶습니다. – Koen
물론 당신은 맞지만 생각합니다. 그것을 연결하는 일반적인 방법입니다. 가독성을 높이기 위해 다음과 같이 메소드를 둘러 쌀 수 있습니다. - (void) doSomthingB {[self doSomethingBWithCompletion :^(NSError * error) { if (error == nil) { }]; .. 블록의 결과는 처음의 결과에 의존하지 않습니다? – Gulliva