我正在学习iOS的并发编程.到目前为止,我已经读过NSOperation/NSOperationQueue和GCD.使用NSOperationQueueover 的原因是什么GCD,反之亦然?
听起来像是两者,GCD并从用户那里NSOperationQueue抽象出明确的创造NSThreads.然而这两种方法之间的关系对我来说并不清楚,所以任何反馈都要赞赏!
concurrency nsoperation nsoperationqueue grand-central-dispatch ios
我正在测试一些使用Grand Central Dispatch进行异步处理的代码.测试代码如下所示:
[object runSomeLongOperationAndDo:^{
STAssert…
}];
Run Code Online (Sandbox Code Playgroud)
测试必须等待操作完成.我目前的解决方案如下:
__block BOOL finished = NO;
[object runSomeLongOperationAndDo:^{
STAssert…
finished = YES;
}];
while (!finished);
Run Code Online (Sandbox Code Playgroud)
看起来有点粗糙,你知道更好的方法吗?我可以通过调用暴露队列然后阻塞dispatch_sync:
[object runSomeLongOperationAndDo:^{
STAssert…
}];
dispatch_sync(object.queue, ^{});
Run Code Online (Sandbox Code Playgroud)
......但是这可能会暴露太多object.
我有一个接受块和完成块的方法.第一个块应该在后台运行,而完成块应该在调用方法的任何队列中运行.
对于后者我总是使用dispatch_get_current_queue(),但似乎它在iOS 6或更高版本中已被弃用.我应该用什么呢?
cocoa-touch objective-c grand-central-dispatch objective-c-blocks ios6
我在我的应用程序中使用了GCD和performSelectorOnMainThread:waitUntilDone,并且倾向于认为它们是可互换的 - 也就是说,performSelectorOnMainThread:waitUntilDone是GCD C语法的Obj-C包装器.我一直在考虑这两个命令是等价的:
dispatch_sync(dispatch_get_main_queue(), ^{ [self doit:YES]; });
[self performSelectorOnMainThread:@selector(doit:) withObject:YES waitUntilDone:YES];
Run Code Online (Sandbox Code Playgroud)
我不对吗?也就是说,performSelector*命令与GCD命令有区别吗?我已经阅读了很多关于它们的文档,但还没有看到明确的答案.
iphone multithreading objective-c grand-central-dispatch ios
在Apple文档中,它说:
要点:您永远不应该从正在计划传递给该函数的同一队列中执行的任务调用dispatch_sync或dispatch_sync_f函数.这对于保证死锁的串行队列尤其重要,但对于并发队列也应该避免.
你如何编写代码才能做到这一点?
我用 DispatchQueue 做了简单的测试:
DispatchQueue.global(qos: .background).sync {
if Thread.isMainThread {
print("Main thread")
}
}
Run Code Online (Sandbox Code Playgroud)
它打印出来:
Main thread
Run Code Online (Sandbox Code Playgroud)
为什么这段代码在主线程上执行?它应该在后台线程上执行(它被添加到后台队列中),对吗?
我相信我知道调用它时调度队列在做什么,但是我不确定何时应该确切地使用它,以及当我使用它时它的优点是什么。
如果我的理解是正确的,DispatchQueue.main.async { // code }将调度包含在闭包中的代码以异步方式在主调度队列上运行。主队列具有最高优先级,通常保留用于更新UI以最大化App响应能力。
我感到困惑的地方是:更新调度队列闭包中的UI元素与只在闭包外的同一位置编写代码有什么区别?在加载了方法的视图主体中执行代码而不是将其发送到调度队列是否更快?如果没有,为什么?
代码示例:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
}
}
Run Code Online (Sandbox Code Playgroud)
与:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
updateUI()
}
}
}
Run Code Online (Sandbox Code Playgroud)
哪个会更快更新UI?
ios ×4
objective-c ×4
concurrency ×2
swift ×2
cocoa-touch ×1
ios6 ×1
iphone ×1
nsoperation ×1
unit-testing ×1
xcode ×1