首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSOperationQueue通知

NSOperationQueue通知
EN

Stack Overflow用户
提问于 2015-02-26 05:43:37
回答 3查看 95关注 0票数 0

帮帮我,或者只是在这个问题上提供一些线索。

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

我希望在NSOperationQueue完成时得到通知,但我不能简单地计算它正在运行的操作的数量。有时,NSOperationQueue有0个操作,因为它依赖于从服务器到达的数据。

NSOperations启动方法

代码语言:javascript
复制
- (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执行的主线程回调

代码语言:javascript
复制
- (void)archiveStoreDidFinish:(ArchiveStoreOperation *)downloader {

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

    [self.pendingOperations.archiveStoreInProgress removeObjectForKey:xmlID];

}

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

代码语言:javascript
复制
- (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;
}

有什么想法吗?先谢谢你...

EN

回答 3

Stack Overflow用户

发布于 2015-02-26 05:53:15

据我所知,每个NSOperation都有一个可以检查的isFinished属性。但是,有一个警告- isFinished不能保证操作已经成功完成。如果成功,则将其设置为true,如果已取消或发生错误,则将其设置为。

显然,每个队列都有一个操作[queue.operations count]的计数,但是正如您所说的,这在这里没有用处。

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

另外,如果你还没有的话,检查一下,然后发布here

票数 0
EN

Stack Overflow用户

发布于 2015-02-26 05:54:26

每当最后一个队列中的NSOperation完成时,我都会使用NSNotificationCenter和post。我假设有一个“最后”队列,也就是在其他队列操作完成后启动的队列。

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

票数 0
EN

Stack Overflow用户

发布于 2015-02-26 08:28:16

从你的问题中并不清楚你做了什么和认为什么条件是“完成”(no operation in queue …什么?)。

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

如果除了其他未完成的操作之外,您还有其他条件,这意味着队列不是“完成”的,那么您需要解释。如果网络下载正在进行,那么您可能需要将这种下载包装在一个操作中。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28730240

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档