2010-05-13 59 views
3

我有一個類WebServiceCaller使用NSURLConnection進行異步調用Web服務。該類提供了一個委託屬性,當完成Web服務調用時,它會在委託上調用方法webServiceDoneWithXXX。當使用委託,需要更好的方式來做順序處理

有幾種Web服務方法可以調用,其中兩種是GetSummary和GetList。

使用WebServiceCaller的類最初既需要總結和列表,以便他們這樣寫的:

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

這工作,但至少有兩個問題:

  1. 的調用被分割跨代表 方法,所以很難看到 序列一目瞭然,但更重要的是它很難控制或 修改序列。
  2. 有時我想打電話只是GetSummary不還的GetList所以我 將不得不使用一個醜陋的類級 狀態變量,告訴 webServiceDoneWithGetSummary是否 調用的GetList與否。

假設GetList不能完成,直到GetSummary完成並返回一些用作輸入到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

確實,獲取Web服務調用的結果是(也應該是)異步的,但是,您希望您的調用按順序發生。一種方法是等待第一個完成之後再調用第二個,並在第一個完成時發佈通知。因此,在你的第一個請求(在你的webServiceCaller中,我假設)的-connectionDidFinishLoading中,發佈一個通知給控制器,告訴它第一個請求成功完成。喜歡的東西:

- (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]; 
} 

然後,回到你的控制器,註冊該通知:

- (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]; 
} 

如果你有很多等候對方像這樣的電話,它會變得非常混亂,很難維護,所以可能有一個你應該考慮的設計模式(目前還沒有人想到)。但是,這種方法對我來說工作得很好。通知有助於使其更有意義,因爲您可以在收到符合某些標準的通知時從控制器調用所有請求。

希望是有道理的。

+0

感謝您的回答。我已經看過這個,它似乎並沒有解決順序一體化問題(除非我錯過了某些東西),但它確實給了我一個解決第二個問題的想法。我會用我的想法來解決這個問題(問題#2)。請讓我知道它看起來是否正確。 – Padawan 2010-05-14 02:41:36

相關問題