NSOperationQueue通知

时间:2015-02-25 21:43:37

标签: objective-c nsoperation nsoperationqueue

在这里帮助我,或者只是解决问题。

我有一个场景,我在openfire服务器上执行存档消息的同步,并使用NSOperationNSOperationQueue来处理和存储所有传入的消息。

我想在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];

}

当我收到包含来自openfire服务器的聊天记录列表的iq节时,这些操作就开始了。然后我像这样处理这些列表:

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

任何想法的人?提前谢谢......

3 个答案:

答案 0 :(得分:0)

根据我的理解,每个NSOperation都有一个isFinished属性,您可以检查。但是,有一个警告 - isFinished不保证操作已成功完成。如果成功,则设置为true,如果已取消或发生错误,则设置为[queue.operations count]

显然每个队列都有一个操作计数{{1}},但正如你所说的那样,这里不会有用。

另一种方法是使用KVO。您可以尝试在您正在使用的其他对象和NSOperationQueue之间进行设置。您可以将一个观察者添加到队列中,并检查没有其他操作生效。


另外,如果您还没有,请查看此SO帖here

答案 1 :(得分:0)

我使用NSNotificationCenter并在最后一个队列中的NSOperation完成时发布。我假设有一个" last"队列,也就是在其他队列操作完成后被启动的队列。

收到通知后,请检查所有NSOperationQueue的计数,看看它们是否为空。

答案 2 :(得分:0)

从你的问题确切地说,你认为“完成”的条件是什么(队列中没有操作,......什么?)。

一种方法是创建完成操作。在创建其他操作时,将每个操作添加为完成操作的依赖项。完成操作可以在其他队列中,可能是[NSOperationQueue mainQueue]。当没有其他未完成的操作时,将执行完成操作。

如果你有其他条件而不是其他未完成的操作意味着队列没有“完成”,那么你需要解释一下。如果正在进行网络下载,那么您可能需要在操作中包装此类下载。

您还可以使用NSOperation的自定义子类进行完成操作,并覆盖-isReady以使用它想要的任何标准来增强超类的准备就绪概念。当然,如果您这样做,则需要在其他条件发生变化时生成KVO更改通知。