我正在学习iOS的并发编程.到目前为止,我已经读过NSOperation
/NSOperationQueue
和GCD
.使用NSOperationQueue
over 的原因是什么GCD
,反之亦然?
听起来像是两者,GCD
并从用户那里NSOperationQueue
抽象出明确的创造NSThreads
.然而这两种方法之间的关系对我来说并不清楚,所以任何反馈都要赞赏!
concurrency nsoperation nsoperationqueue grand-central-dispatch ios
我必须在我的应用程序中执行一系列下载和数据库写入操作.我正在使用NSOperation
和NSOperationQueue
相同的.
这是应用场景:
如上所述,我NSOperation
为每项任务定义了一个.在第一种情况下(Task1),我向服务器发送请求以获取所有邮政编码.将在该会议中的代表NSOperation
接收数据.然后将该数据写入数据库.数据库操作在不同的类中定义.从NSOperation
类I开始调用数据库类中定义的write函数.
我的问题是数据库写操作是在主线程还是后台线程中发生的?正如我在其中调用它一样, NSOperation
我期望它在不同的线程(Not MainThread)中运行NSOperation
.有人可以在处理NSOperation
和解释这个场景时解释NSOperationQueue
.
我正在尝试构建一个批量图像下载器,可以将图像动态添加到队列中进行下载,我可以找到进度以及何时完成下载.
通过我的阅读,似乎NSOperationQueue
对于队列功能和NSURLSession
网络功能似乎是我最好的选择,但我很困惑如何使用这两个串联.
我知道我想补充的情况下,NSOperation
在NSOperationQueue
他们得到排队.似乎我创建了一个下载任务NSURLSessionDownloadTask
,如果我需要多个任务,我会创建多个任务,但我不确定如何将两者放在一起.
NSURLSessionDownloadTaskDelegate
似乎拥有下载进度和完成通知所需的所有信息,但我还需要能够停止特定下载,停止所有下载,并处理从下载中获取的数据.
我无法找到关于如何子类化为NSOperation
并发以及支持取消的良好文档.我阅读了Apple文档,但我无法找到"官方"示例.
这是我的源代码:
@synthesize isExecuting = _isExecuting;
@synthesize isFinished = _isFinished;
@synthesize isCancelled = _isCancelled;
- (BOOL)isConcurrent
{
return YES;
}
- (void)start
{
/* WHY SHOULD I PUT THIS ?
if (![NSThread isMainThread])
{
[self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
return;
}
*/
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];
if (_isCancelled == YES)
{
NSLog(@"** OPERATION CANCELED **");
}
else
{
NSLog(@"Operation started.");
sleep(1);
[self finish];
}
}
- (void)finish
{
NSLog(@"operationfinished.");
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_isExecuting = NO; …
Run Code Online (Sandbox Code Playgroud) 我有一个长时间运行的循环,我想在后台运行一个NSOperation
.我想用一个块:
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
while(/* not canceled*/){
//do something...
}
}];
Run Code Online (Sandbox Code Playgroud)
问题是,如何检查它是否被取消.该块不带任何参数,并且operation
在块被捕获时为零.有没有办法取消块操作?
感谢Stanford的CS193p课程(在iTunes U上)以及Big Nerd Ranch的iOS编程书,我学习了iOS编程.在这两个,他们建议使用dispatch_async()
,dispatch_get_main_queue()
等来处理线程和并发操作.但是,在WWDC 2012关于构建并发UI的会议上,发言人建议使用NSOperationQueue
.
dispatch_*()
和之间NSOperationQueue
有什么区别,有什么理由(技术,性能,风格或其他方面)我应该使用另一个吗?是否NSOperationQueue
只是一个Objective-C的包装器dispatch_async
,或者是有更多的什么原因呢?
目前我正在使用NSThread
另一个线程缓存图像.
[NSThread detachNewThreadSelector:@selector(cacheImage:) toTarget:self withObject:image];
Run Code Online (Sandbox Code Playgroud)
交替:
[self performSelectorInBackground:@selector(cacheImage:) withObject:image];
Run Code Online (Sandbox Code Playgroud)
或者,我可以使用 NSOperationQueue
NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(cacheImage:) object:image];
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:invOperation];
Run Code Online (Sandbox Code Playgroud)
有没有理由改变NSThread
?GCD是iPhone上发布的第四个选项,但除非有显着的性能提升,否则我宁愿坚持使用适用于大多数平台的方法.
根据@ Jon-Eric的建议,我选择了NSOperationQueue
/ NSOperation
子类解决方案.它工作得很好.该NSOperation
班是足够灵活,你可以调用,块或定制子类使用它,这取决于你的需求.无论您如何创建自己,NSOperation
都可以在准备运行时将其放入操作队列中.如果需要,这些操作可以作为您放入队列的对象,也可以作为独立的异步方法运行.由于您可以轻松地同步运行自定义操作方法,因此测试非常简单.
我在一些项目中使用了相同的技术,因为我问了这个问题,我对它保持我的代码和我的测试干净,有条理和快乐异步的方式感到高兴.
A +++++++++++++++++++++++++
我正在尝试实现一个操作队列,我有以下场景:
NSOperation A
NSOperation B
NSOperation C
NSOperation D
NSOperationQueue queue
Run Code Online (Sandbox Code Playgroud)
我开始加入A
到queue
.
在执行期间,A
我需要从中获取一些数据B
,我无法继续,A
直到B
返回我需要的内容.
B
取决于C
和C
取决于相同的情况将发生D
.
为了管理这个,每个NSOperation
我都有这个代码:
NSOperation *operation; //This can be A, B, C, D or any other NSOperation
[self setQueuePriority:NSOperationQueuePriorityVeryLow]; //Set the current NSOperation with low priority
[queue addOperation: operation]; //Add the operation that I want to the queue
while(!operation.isFinished && !self.isCancelled){} //I need to wait the operation that …
Run Code Online (Sandbox Code Playgroud) 正如标题所示,NSOperationQueue的maxConcurrentOperationCount的默认值是多少?
是否设置为1的值?
这有什么区别:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self doSomthing:object];
}];
Run Code Online (Sandbox Code Playgroud)
还有这个:
[self performSelectorOnMainThread:@selector(doSomething:) withObject:object waitUntilDone:NO]
Run Code Online (Sandbox Code Playgroud) nsoperationqueue ×10
nsoperation ×7
ios ×6
objective-c ×5
iphone ×3
concurrency ×2
nsthread ×2
nsurlsession ×1