在这里帮助我,或者只是解决问题。
我有一个场景,我在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];
}
当我收到包含来自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;
}
任何想法的人?提前谢谢......
答案 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更改通知。