ASIHTTPRequest: результаты не заполняются в нужное время при использовании асинхронного запроса - PullRequest
1 голос
/ 03 сентября 2010

У меня есть свой собственный класс, который должен выполнять запрос и обработку данных (анализ). Этот класс следует использовать из разных контроллеров представления. В этом классе я реализовал:

- (void)sendRequest:(NSString *)url;
- (void)requestFinished:(ASIHTTPRequest *)request;
- (void)requestFailed:(ASIHTTPRequest *)request;
- (id)parse:(NSString *)aString;

Я создал свойство с именем result. Если запрос приходит, вызывается requestFinished. В requestFinished результаты сохраняются в результате. Я думал, что если я верну значение в sendRequest, я получу результат обратно. Но, как я упоминал ранее, requestFinished получает результат, и поэтому sendRequest всегда возвращает переменную nil, потому что в то время запрос еще не завершен.

Что я могу сделать, чтобы вернуть результат? Я хочу, чтобы этот класс можно было использовать с разных контроллеров представления. Поэтому моя первая мысль создать метод в моем контроллере представления и передать результат не будет работать.

Я читаю эту ветку Передать результат запроса ASIHTTPRequest "requestFinished" Назад к исходному методу об использовании контроллера представления в качестве делегата. Но тогда я думаю, что я должен реализовать requestFinished и requestFailed в контроллере представления. Идея отсутствия дублирующего кода в разных контроллерах представления исчезнет ...

Может кто-нибудь помочь?

Ответы [ 2 ]

0 голосов
/ 03 сентября 2010

Итак, наконец, я сделал это с делегатом.

В своем классе абстракции (* .h) я определил следующее, в противном случае вы получите

предупреждение: нет метода -setDarkness:найдено

предупреждение: (Будут приняты сообщения без соответствующей сигнатуры метода

предупреждение: вернуть 'id' и принять '...' в качестве аргументов.)

@protocol RssParserDelegate <NSObject>  
    - (void)displayResults:(NSDictionary *)parserResults;
@end

Чем я объявил переменную экземпляра и некоторые методы в своем классе абстракции (* .h):

id _delegate;
// ...
- (id)delegate;  
- (void)setDelegate:(id)new_delegate;

Поэтому объявление выглядит так (* .m):

 - (id)delegate {  
     return _delegate;  
 }  

 - (void)setDelegate:(id)new_delegate {  
     _delegate = new_delegate;  
 }

Чтобы передать результат, вы должны поместить следующий код в requestFailed и requestFinished:

if ([_delegate respondsToSelector:@selector(displayResults:)])
    [_delegate displayResults:results];
else  
{   
    [NSException raise:NSInternalInconsistencyException  
                format:@"Delegate doesn't respond to displayResults:"];  
}

Я переопределил sendRequest и установил входящий делегат в моей переменной экземпляра:

- (void)sendRequest:(NSString *)url withDelegate:(id)aDelegate {
    // set delegate to populate the results later
    [self setDelegate:aDelegate]; 

По вашему мнениюконтроллер объявляет этот метод:

- (void)displayResults:(NSDictionary *)results {
     // do some data processing
     ...
     // show data
     [self.tableView reloadData];
}

И я также изменил вызов метода на sendRequest моего класса абстракции:

[yourRequest sendRequest:@"xxx" withDelegate:self]; 
0 голосов
/ 03 сентября 2010

Отправляйте уведомление наблюдателя всякий раз, когда вы получаете результат, и ваши контроллеры представления добавляют себя в качестве слушателей этого уведомления (получая его через [объект уведомления]).

...