gpt4 book ai didi

iphone - 使用委托(delegate)时,需要更好的方法来进行顺序处理

转载 作者:搜寻专家 更新时间:2023-10-30 20:27:31 24 4
gpt4 key购买 nike

我有一个 WebServiceCaller 类,它使用 NSURLConnection 对 Web 服务进行异步调用。该类提供委托(delegate)属性,当 Web 服务调用完成时,它会调用委托(delegate)上的方法 webServiceDoneWithXXX。

可以调用多个 Web 服务方法,其中两个是 GetSummary 和 GetList。

使用WebServiceCaller的类最初需要summary和list,所以写成这样:

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

这可行,但至少有两个问题:

  1. 调用被分配给委托(delegate)方法,所以很难看到顺序一目了然,但更多重要的是很难控制或修改顺序。
  2. 有时我只想调用 GetSummary 而不是 GetList,所以我然后将不得不使用丑陋的类级别状态变量告诉webServiceDoneWithGetSummary 是否是否调用 GetList。

假设 GetList 在 GetSummary 完成并返回一些用作 GetList 输入的数据之前无法完成。

有没有更好的方法来处理这个问题并仍然获得异步调用?

根据 Matt Long 的回答更新:

使用通知而不是委托(delegate),看起来我可以通过设置不同的选择器来解决问题 #2,具体取决于我是想要完整序列 (GetSummary+GetList) 还是只需要 GetSummary。调用 GetSummary 时,两个观察者仍将使用相同的通知名称。我将不得不编写两个单独的方法来处理 GetSummaryDone,而不是使用单个委托(delegate)方法(我需要一些类级变量来判断是否随后调用 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 的解决方案。

最佳答案

的确,获取 Web 服务调用的结果是(而且应该是)异步的,但是,您希望调用按顺序发生。一种方法是在调用第二个之前等待第一个完成,并在第一个完成时发布通知。因此,在您的第一个请求的 -connectionDidFinishLoading 中(我假设在您的 webServiceCaller 中),将通知发回您的 Controller ,告诉它第一个请求已成功完成。像这样的东西:

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

然后,回到您的 Controller 中,注册该通知:

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

如果您有很多像这样相互等待的调用,它会变得非常困惑并且难以维护,因此您可能应该考虑一种设计模式(目前还没有想到)。但是,这种方法对我来说效果很好。通知有助于它更有意义,因为当您收到满足某些条件的通知时,您可以从 Controller 调用所有请求。

希望这是有道理的。

关于iphone - 使用委托(delegate)时,需要更好的方法来进行顺序处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2829290/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com