2010-05-13 1 views
3

NSURLConnection을 사용하여 웹 서비스에 대한 비동기 호출을 만드는 클래스 WebServiceCaller가 있습니다. 이 클래스는 대리자 속성을 제공하며 웹 서비스 호출이 완료되면 대리자의 webServiceDoneWithXXX 메서드를 호출합니다.대리자를 사용할 때 순차 처리를 더 잘 수행 할 방법이 필요합니다.

호출 할 수있는 몇 가지 웹 서비스 메서드가 있는데, 그 중 두 가지는 GetSummary 및 GetList입니다. 그들은 다음과 같이 작성되도록 WebServiceCaller를 사용

클래스는 처음에 요약 및 목록이 모두 필요 :

-(void)getAllData { 
    [webServiceCaller getSummary]; 
} 
-(void)webServiceDoneWithGetSummary { 
    [webServiceCaller getList]; 
} 
-(void)webServiceDoneWithGetList { 
    ... 
} 

이 작동하지만 적어도 두 가지 문제가 있습니다 : 호출이 분할

  1. 가 위임자는 메서드를 사용하므로 시퀀스를 한 눈에 볼 수 있지만 더 이상 은 제어하기가 어렵거나 시퀀스를 수정하는 것이 중요합니다.
  2. 때때로 나는 또한 GetList 내가 다음 GetList 여부를 호출 할 여부를 webServiceDoneWithGetSummary 알려줍니다 추한 클래스 수준 상태 변수를 사용하는 것뿐만 아니라 GetSummary를 호출합니다.

GetSummary가 완료되고 GetList에 대한 입력으로 사용되는 일부 데이터를 반환 할 때까지 GetList를 수행 할 수 없다고 가정합니다.

이 문제를 처리하고 비동기 호출을받는 더 좋은 방법이 있습니까? 매트 롱의 답변에 따라

업데이트 : 대신 대리인의 알림을 사용

, 내가 GetSummary + GetList 내가 전체 순서를 (여부에 따라 다른 선택을 설정하여 문제 # 2를 해결할 수처럼 보인다) 또는 단지 GetSummary. 두 관찰자 모두 GetSummary를 호출 할 때 동일한 알림 이름을 사용합니다. 하나의 델리게이트 메소드를 사용하는 대신 GetSummaryDone을 ​​처리하기 위해 두 개의 분리 된 메소드를 작성해야합니다 (여기서 GetList를 호출할지 여부를 알기 위해 클래스 레벨 변수가 필요할 수 있습니다).

-(void)getAllData { 
    [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(getSummaryDoneAndCallGetList:) 
                 name:kGetSummaryDidFinish object:nil]; 
    [webServiceCaller getSummary]; 
} 
-(void)getSummaryDoneAndCallGetList { 
    [NSNotificationCenter removeObserver] 
    //process summary data 

    [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(getListDone:) 
                 name:kGetListDidFinish object:nil]; 
    [webServiceCaller getList]; 
} 
-(void)getListDone { 
    [NSNotificationCenter removeObserver] 
    //process list data 
} 


-(void)getJustSummaryData { 
    [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(getJustSummaryDone:)  //different selector but 
                 name:kGetSummaryDidFinish object:nil]; //same notification name 
    [webServiceCaller getSummary]; 
} 
-(void)getJustSummaryDone { 
    [NSNotificationCenter removeObserver] 
    //process summary data 
} 

아직 실제로 시도하지 않았습니다. 상태 변수와 if-then 문보다 더 나은 방법이 있지만 더 많은 방법을 써야합니다. 여전히 문제 1에 대한 해결책이 보이지 않습니다.

답변

2

웹 서비스 호출의 결과를 얻는 것은 비동기 적이며 비동기 적이어야하지만, 호출이 순서대로 이루어지기를 바랍니다. 한 가지 방법은 두 번째 전화를 걸기 전에 첫 번째 전화가 끝날 때까지 기다렸다가 첫 번째 전화가 오면 알림을 게시하는 것입니다. 따라서 첫 번째 요청이 -connectionDidFinishLoading 인 경우 (webServiceCaller에서 가정 함) 컨트롤러에 첫 번째 요청이 성공적으로 완료되었다는 알림을 게시합니다.뭔가 같이 :이 같은 서로 기다릴 전화가 많은 경우

- (void)viewDidLoad; 
{ 
    [super viewDidLoad]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
      selector:@selector(getSummaryDidFinish:) 
       name:kGetSummaryDidFinish object:nil]; 
} 

- (void) getSummaryDidFinish:(NSNotification*)notification; 
{ 
    // If you needed the downloaded data, we passed it in 
    NSData *data = [notification object]; 

    // Decide here if you want to call getList or not. 
    if (someConditionOfDataObjectIsTrue) 
     [webServiceCaller getList]; 
} 

, 그것은 매우 혼란 스러울 수 있으며, 그런 다음

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    [connection release]; 
    // receivedData is an NSMutableData object we've been appending 
    // to in the -didReceiveData delegate. We'll pass it in the 
    // notification so we can hand the data off to the next request. 
    [[NSNotificationCenter defaultCenter] 
      postNotificationName:kGetSummaryDidFinish object:receivedData]; 
} 

, 다시 컨트롤러, 그 통지에 등록 유지하기가 어려우므로 고려해야 할 디자인 패턴이있을 수 있습니다 (현재로서는 마음에 들지 않습니다). 그러나,이 방법은 나를 위해 꽤 잘 작동했습니다. 알림은 일부 기준을 충족하는 알림을받을 때 컨트롤러에서 모든 요청을 호출 할 수 있기 때문에 더 유용합니다.

희망이 있습니다.

+0

답변 해 주셔서 감사합니다. 나는 이것을 살펴 봤는데 (뭔가를 놓치지 않았다면) sequencing-in-one-place 문제를 해결하는 것 같지 않지만 두 번째 문제를 해결할 아이디어를 얻는다. 알림을 사용하여 문제를 해결할 것이라고 생각하는 방법으로 문제를 업데이트합니다 (문제 # 2). 제대로 보이는지 알려주세요. – Padawan

관련 문제