并发 NSOperationQueue 上传,后跟单个任务
Posted
技术标签:
【中文标题】并发 NSOperationQueue 上传,后跟单个任务【英文标题】:concurrent NSOperationQueue uploads followed by a single task 【发布时间】:2013-09-11 05:24:19 【问题描述】:我正在尝试执行两步流程:
-
同时上传照片
用户输入然后发布内容
,这与“添加照片”时 facebook 应用程序的工作方式非常相似
我想先在后台使用默认的NSOperationQueueDefaultMaxConcurrentOperationCount
开始上传照片。这些操作将返回一些我需要与第二个帖子一起发送的信息。
但是,由于应用程序的性质和并发性,我如何才能以仅在满足以下条件时才发布内容的方式构建它:
-
所有照片已上传
发布内容的用户操作
可能会发生几种情况:
-
没有照片可发布,用户发布内容,内容应立即发布
图片上传完成,用户发布内容,内容应立即发布
照片上传未完成,用户发布内容,需要等待所有照片上传完成才能发布内容。
我想我应该创建一个照片上传NSOperationQueue
并检查operationCount
。如果为== 0,则内容应在用户点击UIButton
时立即发布。
但是,如果照片上传未完成,我该如何等待?我是否应该在伪代码中以下列方式使用waitUntilAllOperationsAreFinished
:
// User taps on UIButton to post his content and this is in a ViewController
- void postMyContent:
[self.photoUploadQ.waitUntilAllOperationsAreFinished]
// Post my content now
这是正确的吗?我无法将第二个任务添加到 photoUploadQ
,因为它具有默认并发。
由于文档,我担心死锁/阻塞:
调用时,此方法会阻塞当前线程并等待接收者的当前和排队操作完成执行。当当前线程被阻塞时,接收器继续启动已经排队的操作并监视那些正在执行的操作。在此期间,当前线程无法向队列添加操作,但其他线程可以。一旦所有挂起的操作都完成了,这个方法就会返回。
如果队列中没有操作,则该方法立即返回。
谢谢!
【问题讨论】:
再次阅读文档。看来我可以将第二个任务交给addDependency
,以上传所有照片NSOperation
。我不确定您是否可以有多个相关任务。这也意味着如果没有可依赖的,我可以做一个简单的operationCount
。
我不应该依赖默认值吗?我想这也取决于连接的类型。
..请在此处分享您的更新代码,以便在 xcode 工作区中逐步使用上传图片
【参考方案1】:
一种常见的操作队列模式是创建一个操作(在您的情况下为“发布内容”操作),该操作依赖于一系列其他操作(在您的情况下为“图像上传”操作)的完成,使用NSOperation
方法,addDependency
。这样,虽然队列可能是并发的,但在其他“图片上传”操作完成之前,该“发布内容”操作不会开始。
您可能还希望将您的操作队列限制为小于NSOperationQueueDefaultMaxConcurrentOperationCount
,因为NSURLConnection
通常只允许 5 个左右的并发操作(如果您做的更多,其中一些最终可能会超时)。
【讨论】:
我也发现了这个github.com/Weswit/utility-ThreadPool-ios,当队列不遵守最大计数时它会有所帮助。 @NoraOlsen 如果这对你有用,那就太好了。我不得不说我做了很多并发的网络操作,我从来没有经历过they describe 这种行为,他们声称maxConcurrentOperationCount
不被尊重。如果他们使用NSInvocationOperation
或NSBlockOperation
,他们会遇到问题也就不足为奇了,但是如果使用正确实现的NSOperation
子类(使用并发操作所需的isFinished
逻辑),我从来没有遇到过问题。
我也可以确认 Rob 的经历。实际上,我编写了一个测试,但无法重现 NSOperationQueue 的错误行为——前提是 NSOperation 已被正确子类化。而且,顺便说一下,在传输大数据(如图像)时,一次使用单个连接可能会更好。
谢谢。我在这方面没有太多经验。例如:多 M 个帖子,每个 N 个图像或 M*N 个帖子每个 1 个图像会更好?
我也测试过。由于我使用的是 RestKit/AFNetworking,因此当 NSOperationQueue 不尊重 maxConcurrentOperationCount
时,我没有看到这种行为。以上是关于并发 NSOperationQueue 上传,后跟单个任务的主要内容,如果未能解决你的问题,请参考以下文章
CoreData 并发 - 我需要一个单独的 NSOperationQueue 吗?