2013-10-04 2 views
1

Я одновременно загружаю некоторую информацию с сервера, и я использую NSOperatioQueue для этого же. У меня проблема. Например, если по какой-либо причине не удается выполнить операцию загрузки, я не хочу удалять эту операцию из очереди.NSOperation и NSOperationQueue

Прямо сейчас, даже если его сбой, как только он получает ответ от сервера, операция удаляется из очереди.

Есть ли способ сообщить очереди, что конкретная операция не выполнена логически и она должна содержать ее в очереди?

В моем случае я загружаю набор информации. Например, выбирая все места в округе, а затем все дома для каждого округа. Поэтому в некоторых случаях графство не может быть загружено, если пользователь не вошел в систему с действительным токеном. В этом случае сервер возвращает сообщение об ошибке. Я хочу сохранить такие элементы в очереди, чтобы снова попробовать, когда пользователь входит в приложение.

Пример кода

self.downloadQueue.maxConcurrentOperationCount = 1; 
    for(Campaign *campaign in campaigns) 
    { 
     isContentUpdated = false; 
     if(self.operation) 
      self.operation = Nil; 
     self.operation = [[DownloadOutlets alloc] initWithCampaign:campaign]; 
     [self.downloadQueue addOperation:operation]; 
    } 

где downloadQueue является NSOperationQueue и DownloadOutlets расширяет NSOperation. Thanks

+0

Как работают ваши операции? Покажите примеры кода. –

+0

Что это значит? Зачем вам делать операцию в очереди, если она уже выполнила весь код (был ли он успешным или неудачным)? – micantox

+0

В моем случае, я загружаю набор информации. Например, выбирая все места в округе, а затем все дома для каждого округа. Поэтому в некоторых случаях графство не может быть загружено, если пользователь не вошел в систему с действительным токеном. В этом случае сервер возвращает сообщение об ошибке. Я хочу держать такие предметы в очереди. – Zach

ответ

1

Вы не должны держать свои неудавшиеся операции в очереди. Неисправная операция выполнила свою задачу. Вам необходимо, чтобы ваш контроллер операции прослушивал состояние операций через completionBlock или иным образом и решил, что делать дальше. Если дело доходит до определения того, что операция потерпела неудачу, но аналогичная операция должна быть повторена, она должна добавить еще одну операцию для повторной задачи.

Другим подходом было бы повторить попытку загрузки внутри операции до достижения успеха и только затем завершить операцию. Однако это не оптимальный дизайн, поскольку операция не требует и не должна содержать всю информацию, необходимую для принятия решения о том, следует ли повторять попытку, информировать пользователя и т. Д.

0

Не следует выполнять операции, которые не выполнялись в очереди, но использовать очереди для последовательной выборки данных и остановки очереди, если операция не выполняется:

@implementation DataAdapter 
// ... 

-(void)setup{ 
    // weak reference to self to avoid retain cycle 
    __weak DataAdapter* selfRef= self; 

    // create a block that will run inside the operation queue 
    void(^pullCountriesBlock)(void)= ^{ 
      [[DownloadManager instance] fetchAllCountriesWithCompletionBlock:^(Result* result){ 
      if(result.successful){ 
       // on success 
       [selfRef didFetchDataForAction:action]; 
      }else{ 
       // on failure 
       [selfRef failedToFetchDataForAction:action]; 
      } 
    }; 

    self.actions= [NSMutableArray new]; 
    [self.actions addObject:[DownloadAction actionWithBlock:pullCountriesBlock]; 
    // add other actions 
    // ... 
    [self fetchData]; 
} 

} 

-(void)fetchData{ 
    if(self.currentActionIndex >= self.actions.count){ 
      [self finishedFetchingData]; 
      return; 
    } 

    [self fetchDataForAction: self.actions[self.currentActionIndex] ]; 
} 

-(void)fetchDataForAction:(DownloadAction*)action 
     [self.myOperationQueueImplementation enqueueOperationWithBlock:action.block]; 
} 

Если загрузка прошла успешно, только епдиеие следующее действие (приращение currentActionIndex и вызова fetchData). Если это не удается, вы можете действовать соответствующим образом. Я бы начал прослушивать интересные события NSNotificationCenter перед вызовом fetchData в первый раз. Вы можете прослушивать UserDidLogInNotification или любой другой, который может позволить очереди продолжать загрузку.

Смежные вопросы