2010-05-13 28 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

相关问题