2015-02-25 5 views
0

Помогите мне здесь или просто пролить свет на проблему.Уведомление NSOperationQueue

У меня есть сценарий, в котором я выполняю синхронизацию архивных сообщений на сервере openfire, и я обрабатываю и сохраняю все входящие сообщения с NSOperation и NSOperationQueue.

Я хочу получить уведомление, когда сделано NSOperationQueue, но я не могу просто подсчитать количество выполняемых операций. Время от времени NSOperationQueue имеет 0 операций, потому что это зависит от данных, которые необходимо получить от сервера.

Методы NSOperations начала

- (void)startArchiveSyncStore:(XMPPIQ *)iq operationID:(NSString *)xmlID { 

    @autoreleasepool { 

     if (![self.pendingOperations.archiveStoreInProgress.allKeys containsObject:xmlID]) { 

      ArchiveStoreOperation *storeOperation = [[ArchiveStoreOperation alloc] initWithMessagesToArchive:iq withID:xmlID delegate:self]; 

      [self.pendingOperations.archiveStoreInProgress setObject:storeOperation forKey:xmlID]; 
      [self.pendingOperations.archiveStoreQueue addOperation:storeOperation]; 

     } 
    } 
} 

- (void)startArchiveSycnDownload:(XMPPIQ *)iq operationID:(NSString *)xmlID { 

    @autoreleasepool { 

     if (![self.pendingOperations.archiveDownloadInProgress.allKeys containsObject:xmlID]) { 

      ArchiveDownloadOperation *downloadOperation = [[ArchiveDownloadOperation alloc] initWithMessagesToDownload:iq withID:xmlID delegate:self]; 

      [self.pendingOperations.archiveDownloadInProgress setObject:downloadOperation forKey:xmlID]; 
      [self.pendingOperations.archiveDownloadQueue addOperation:downloadOperation]; 

     } 
    } 
} 

И это главный обратный вызов резьбы в исполнении NSOperation:

- (void)archiveStoreDidFinish:(ArchiveStoreOperation *)downloader { 

    NSString *xmlID = downloader.xmlnsID; 
    DDLogInfo(@"%@ %@", THIS_METHOD, xmlID); 

    [self.pendingOperations.archiveStoreInProgress removeObjectForKey:xmlID]; 

} 

Эти операции начинаются, когда я получаю Iq строфы, содержащие списки истории чата из openfire server. Затем я обрабатываю эти списки следующим образом:

- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq { 

    if ([iq isResultIQ]) { 

     if ([iq elementForName:@"list" xmlns:@"urn:xmpp:archive"]) { 

      [self startArchiveSycnDownload:iq operationID:[[iq attributeForName:@"id"] stringValue]]; 
     } 
     if ([iq elementForName:@"chat" xmlns:@"urn:xmpp:archive"]) { 

      [self startArchiveSyncStore:iq operationID:[[iq attributeForName:@"id"] stringValue]]; 
     } 
    } 

    return NO; 
} 

Любые идеи? Спасибо заранее ...

ответ

0

Из моего понимания каждый NSOperation имеет свойство isFinished, которое вы можете проверить. Но есть оговорка - isFinished не гарантирует успешного завершения операции. Он установлен в true, если он преуспевает, но также и если он был отменен или произошла ошибка.

Очевидно, что каждая очередь имеет счетчик операций [queue.operations count], но, как вы уже сказали, это будет бесполезно.

Один из вариантов заключается в использовании KVO. Вы можете попробовать установить это между другим объектом, который вы используете, и NSOperationQueue. Вы можете добавить наблюдателя в очередь и проверить, что другие операции не действуют.


Кроме того, проверить это ТАК опубликовать here, если вы еще не сделали.

0

Я использую NSNotificationCenter и отправляю всякий раз, когда NSOperation в последней очереди заканчивается. Я предполагаю, что есть «последняя» очередь, а также та, которая закручивается после завершения других операций с очередью.

Когда вы получаете уведомление, проверьте количество всех ваших NSOperationQueue s, чтобы узнать, пусты ли они.

0

Непонятно из вашего вопроса, какое именно условие вы do считают «выполненным» (никаких операций в очереди и ... что?).

Один из подходов заключается в создании операции завершения. Когда вы создаете другие операции, добавьте их как зависимость от операции завершения. Операция завершения может быть в некоторой другой очереди, возможно, [NSOperationQueue mainQueue]. Когда других операций не будет выполнено, выполняется операция завершения.

Если у вас есть другое условие, отличное от других операций, то это означает, что очередь не выполнена, тогда вам нужно объяснить. Если это происходит при загрузке сети, возможно, вам придется переносить такую ​​загрузку в операцию.

Вы также можете использовать пользовательский подкласс NSOperation для операции завершения и переопределить -isReady, чтобы использовать любые критерии, которые он хочет расширить, над уровнем готовности суперкласса. Конечно, если вы это сделаете, вам нужно будет генерировать уведомления об изменениях KVO, когда эти другие критерии меняются.

+0

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

+0

Как узнать, есть ли еще сообщения, поступающие с сервера? –

+0

Я предполагаю, что если проверка '- (BOOL) xmppStream: (XMPPStream *) didReceiveIQ: (XMPPIQ *) iq;' метод не вызывается? –