我正在测试一些使用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_async(dispatch_get_main_queue(), ^{ ... do stuff
Run Code Online (Sandbox Code Playgroud)
甚至
dispatch_sync(dispatch_get_main_queue(), ^{ ... do stuff
Run Code Online (Sandbox Code Playgroud)
我的意思是,在这两种情况下,你都要触发一个块来在主线程上执行,确切地说应用程序在哪里运行,这无助于减少负载.在第一种情况下,当块运行时,您没有任何控制权.我已经看到在你开火后半秒执行块的情况.第二种情况,它类似于
[self doStuff];
Run Code Online (Sandbox Code Playgroud)
对?
我想知道你们的想法是什么.
我希望for循环向firebase发送一堆网络请求,然后在方法完成执行后将数据传递给新的视图控制器.这是我的代码:
var datesArray = [String: AnyObject]()
for key in locationsArray {
let ref = Firebase(url: "http://myfirebase.com/" + "\(key.0)")
ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
datesArray["\(key.0)"] = snapshot.value
})
}
// Segue to new view controller here and pass datesArray once it is complete
Run Code Online (Sandbox Code Playgroud)
我有几个问题.首先,我如何等待for循环完成并且所有网络请求都已完成?我无法修改observeSingleEventOfType函数,它是firebase SDK的一部分.另外,我是否会通过尝试从for循环的不同迭代中访问datesArray来创建某种竞争条件(希望这是有道理的)?我一直在阅读有关GCD和NSOperation的内容,但我有点失落,因为这是我构建的第一个应用程序.
注意:Locations数组是一个包含我需要在firebase中访问的键的数组.此外,重要的是异步触发网络请求.我只想等到所有异步请求完成后再将datesArray传递给下一个视图控制器.
我已经创建了一个这样的串行队列:
dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);
Run Code Online (Sandbox Code Playgroud)
dispatch_async叫做这样的有什么区别
dispatch_async(_serialQueue, ^{ /* TASK 1 */ });
dispatch_async(_serialQueue, ^{ /* TASK 2 */ });
Run Code Online (Sandbox Code Playgroud)
而dispatch_sync像这样调用这个串行队列?
dispatch_sync(_serialQueue, ^{ /* TASK 1 */ });
dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });
Run Code Online (Sandbox Code Playgroud)
我的理解是,无论使用哪种调度方法,TASK 1都会在执行和完成之前TASK 2,对吗?
我正在努力完全理解GCD中的并发和串行队列.我有一些问题,希望有人能够清楚地回答我.
我正在读取串行队列的创建和使用,以便一个接一个地执行任务.但是,如果出现以下情况:
dispatch_async(在我刚创建的串行队列上)三次来发送三个块A,B,C这三个块会被执行:
按顺序A,B,C,因为队列是串行的
要么
我正在阅读我可以dispatch_sync在并发队列上使用,以便一个接一个地执行块.在这种情况下,为什么串行队列甚至存在,因为我总是可以使用并发队列,我可以根据需要同步调度多个块?
谢谢你的任何好解释!
我有一个接受块和完成块的方法.第一个块应该在后台运行,而完成块应该在调用方法的任何队列中运行.
对于后者我总是使用dispatch_get_current_queue(),但似乎它在iOS 6或更高版本中已被弃用.我应该用什么呢?
cocoa-touch objective-c grand-central-dispatch objective-c-blocks ios6
我正在阅读关于"调度队列的内存管理"的苹果文档:
即使您实现了垃圾收集的应用程序,您仍必须保留并释放调度队列和其他调度对象.Grand Central Dispatch不支持回收内存的垃圾收集模型.
我知道ARC不是垃圾收集器,但我想确定我不需要dispatch_retain和dispatch_release我的dispatch_queue_t
我怎么能让我的代码等到DispatchQueue中的任务完成?它需要任何CompletionHandler或其他东西吗?
func myFunction() {
var a: Int?
DispatchQueue.main.async {
var b: Int = 3
a = b
}
// wait until the task finishes, then print
print(a) // - this will contain nil, of course, because it
// will execute before the code above
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Xcode 8.2并在Swift 3中编写.
multithreading asynchronous grand-central-dispatch swift swift3
dispatch_once在语言版本3中进行更改后,Swift中的新语法是什么?旧版本如下.
var token: dispatch_once_t = 0
func test() {
dispatch_once(&token) {
}
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以是很清楚的用例解释的目的dispatch_sync在GCD为?我无法理解我必须使用它的地点和原因.
谢谢!
ios ×4
objective-c ×3
swift ×3
asynchronous ×2
concurrency ×2
cocoa ×1
cocoa-touch ×1
ios4 ×1
ios6 ×1
nsoperation ×1
swift3 ×1
unit-testing ×1