У меня есть класс WebServiceCaller, который использует NSURLConnection для выполнения асинхронных вызовов веб-службы. Класс предоставляет свойство делегата и, когда вызов веб-службы завершен, вызывает делегата метод webServiceDoneWithXXX.
Существует несколько методов веб-службы, которые можно вызвать, например, GetSummary и GetList.
Классы, которые используют WebServiceCaller, изначально нуждаются как в сводке, так и в списке, поэтому они пишутся так:
-(void)getAllData {
[webServiceCaller getSummary];
}
-(void)webServiceDoneWithGetSummary {
[webServiceCaller getList];
}
-(void)webServiceDoneWithGetList {
...
}
Это работает, но есть как минимум две проблемы:
- Вызовы распределены по делегату.
методы, поэтому трудно увидеть
последовательность с первого взгляда, но больше
важно, что это трудно контролировать или
изменить последовательность.
- Иногда я хочу вызвать только GetSummary, а не GetList, поэтому я
тогда придется использовать уродливый уровень класса
переменная состояния, которая сообщает
webServiceDoneWithGetSummary ли
вызывать GetList или нет.
Предположим, что GetList нельзя выполнить до тех пор, пока GetSummary не завершит работу и не вернет некоторые данные, которые используются в качестве входных данных для GetList.
Есть ли лучший способ справиться с этим и получать асинхронные вызовы?
Обновление на основе ответа Мэтта Лонга:
Используя уведомления вместо делегата, похоже, что я могу решить проблему # 2, установив другой селектор в зависимости от того, хочу ли я полную последовательность (GetSummary + GetList) или просто 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.