2016-09-22 3 views
0

서버로 여러 요청을 보내서 게시물과 설명을 차례로 가져오고 싶습니다. 그래서, 모든 POSTS를 하나씩 순차적으로 가져 오는 dispatch_group을 사용하여이 예제를 만들었고 POSTS로 끝내면 차례로 주석을 가져옵니다.dispatch_group을 사용한 중첩 된 다중 요청

다음은 어떻게 작동하는지 대략적인 스키마입니다.

  • 후 1
  • 반입 후 페치 2
  • 포스트 50
  • 1
  • 2
  • 의견 페치 의견 페치 페치 후 3
  • 를 .... 오기. ..
  • 의견 가져 오기 50

그래서이 모든 것들은 그림과 같이 연속적으로 작동해야합니다. 게시물 1을 가져오고, 끝내고, 게시물 2 끝내기 등을 가져 오는 것입니다.

다음 예제는 용도에 맞게 작동합니다. 하지만 이제는 50 개의 게시물 동기화가 완료되었을 때와 50 개의 댓글이 완료되었을 때 실제로 알기 위해 전화를 받고 싶습니다. 나는 requestOne과 requestTwo에 for 루프 이후에 dispatch_group_notify를 추가하여이를 시도했다. 그러나 모든 작업이 완료되면 notify 메서드가 호출 된 것 같습니다. 어떻게 달성 될 수 있습니까? 나는 영어 원어민이 아니기 때문에 글을 향상시킬 필요가 있다면 적어주세요. 아직 시도 할 수 있습니다 :)

@interface GroupTest() 

@property (nonatomic, readonly) dispatch_group_t group; 
@property (nonatomic, readonly) dispatch_queue_t serialQueue; 

@end 


@implementation GroupTest 

- (instancetype)init 
{ 
    if (self = [super init]) { 
     _group = dispatch_group_create(); 
     _serialQueue = dispatch_queue_create("com.test.serial.queue", 
              DISPATCH_QUEUE_SERIAL); 
    } 
    return self; 
} 

- (void)start 
{ 
    dispatch_async(self.serialQueue, ^{ 

     [self requestOneCompletion:^{ 
      NSLog(@"Request 1 completed"); 
     }]; 

     [self requestTwoCompletion:^{ 
      NSLog(@"Request 2 completed"); 
     }]; 

    }); 
} 
- (void)requestTwoCompletion:(void(^)(void))completion 
{ 
    for (NSUInteger i = 1; i <= 50; i++) { 
     dispatch_group_enter(self.group); 
     [self requestComment:i 
       completion:^(id response){ 
        NSLog(@"%@", response); 
        dispatch_group_leave(self.group); 
       }]; 
     dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER); 
    } 

} 


- (void)requestOneCompletion:(void(^)(void))completion 
{ 
    for (NSUInteger i = 1; i <= 50; i++) { 
     dispatch_group_enter(self.group); 
     [self requestPost:i 
       completion:^(id response){ 
        NSLog(@"%@", response); 
        dispatch_group_leave(self.group); 
       }]; 
     dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER); 
    } 
} 

- (void)requestComment:(NSUInteger)comment 
      completion:(void(^)(id))completion 
{ 
    NSString *urlString = [NSString stringWithFormat:@"https://jsonplaceholder.typicode.com/comments/%lu", (unsigned long)comment]; 

    NSURLSession *session = [NSURLSession sharedSession]; 
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:urlString] 
      completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 
       id object = [NSJSONSerialization JSONObjectWithData:data 
                  options:0 
                  error:nil]; 
       completion(object); 
      }]; 
    [dataTask resume]; 

} 

- (void)requestPost:(NSUInteger)post 
     completion:(void(^)(id))completion 
{ 
    NSString *urlString = [NSString stringWithFormat:@"https://jsonplaceholder.typicode.com/posts/%lu", (unsigned long)post]; 

    NSURLSession *session = [NSURLSession sharedSession]; 
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:urlString] 
      completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 
       id object = [NSJSONSerialization JSONObjectWithData:data 
                  options:0 
                  error:nil]; 
       completion(object); 
      }]; 
    [dataTask resume]; 
} 

@end 

답변

0

나는 당신이하고 싶은 것이 다음과 같다고 생각합니다. 모든 호출이 완료되면 requestTwoCompletionrequestOneCompletion의 각 완료 블록이 호출되도록이 작업이 수행됩니다. 50 건의 전화 주문은 보장되지 않습니다.

내가 만든 주요 변경 사항은 dispatch_group_t이며 각 방법에 로컬이며 dispatch_group_waitfor 루프 외부로 이동했습니다. 이 경우에는 대기 시간이 단위를 차단할 것이기 때문에 completion의 이점이 없어집니다. 사용 완료 및 사용 중지가 매우 강하게 요구되는 경우 dispatch_async에이 모든 내용을 포함 할 수 있습니다. 이 직렬 대기열에 따라

- (void)requestTwoCompletion:(void(^)(void))completion 
{ 
    dispatch_group_t group = dispatch_group_create(); 

    for (NSUInteger i = 1; i <= 50; i++) { 
     dispatch_group_enter(group); 
     [self requestComment:i 
       completion:^(id response){ 
        NSLog(@"%@", response); 
        dispatch_group_leave(group); 
       }]; 
    } 

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

    completion(); 
} 


- (void)requestOneCompletion:(void(^)(void))completion 
{ 
    dispatch_group_t group = dispatch_group_create(); 

    for (NSUInteger i = 1; i <= 50; i++) { 
     dispatch_group_enter(group); 
     [self requestPost:i 
       completion:^(id response){ 
        NSLog(@"%@", response); 
        dispatch_group_leave(group); 
       }]; 
    } 

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 
} 

,이 작동하는 방식은 requestOneCompletion가 50 개를 완료됩니다 다음 requestTwoCompletion 다음 50를 실행하는 것이다.