我有一组调度工作项,如何等到一项工作完成后再继续队列中的下一项工作?
func AsyncCalls(statusHandler: @escaping (String) -> Void){
var dispatchWorkItems : [DispatchWorkItem] = []
let categoryWorkItem = DispatchWorkItem {
main {
return statusHandler("Loading categories ")
}
self.modelView.getCategories(completion: { data,error in
main {
if data.isEmpty {
return statusHandler("\(error )")
}else{
return statusHandler("Done loading categories")
}
}
})
}
let itemsWorkItem = DispatchWorkItem {
main {
return statusHandler("Loading Inventory ")
}
self.modelView.getInventory(completion: { data,error in
main {
if data.isEmpty {
return statusHandler("\(error )")
}else{
return statusHandler("Done loading Inventory")
}
}
})
}
dispatchWorkItems.append(categoryWorkItem) …Run Code Online (Sandbox Code Playgroud) dispatch grand-central-dispatch dispatch-async swift dispatch-queue
假设我们有一个共享资源,许多不同的全局队列都可以访问该资源,并且为了解决这个问题,我们使用调度信号量来管理该访问。当这些全局队列之一告诉信号量等待时,信号量计数就会递减,并且该线程可以访问共享资源。是否有可能在信号量等待时,另一个(不同的)全局队列尝试访问这个共享资源,而GCD从其池中抓取的线程与为前一个队列(当前正在制作的队列)抓取的线程相同信号量等待)这会导致该线程死锁并阻止信号量计数重新递增?
我\xe2\x80\x99m很好奇DispatchQueue到底是什么,我试图用谷歌搜索这些信息,但所有文档都相当抽象,并且不\xe2\x80\x99t提供有关实现的任何真实信息。在我的理解中,DispatchQueue是某种存在于某处的实体,能够存储代码块,并由内核直接控制(通过GCD,它被烘焙到内核中),它能够将这些块注入到所选中(通过GCD) /内核)线程。这是 DispatchQueue 的正确愿景,还是我误解了什么?
\n我写一个演示
let queue = DispatchQueue.global()
queue.async {
let group = DispatchGroup()
group.enter()
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now(), qos: .default) {
//do sth in default queue
group.leave()
}
group.wait()
DispatchQueue.main.async { [weak self] in
//do sth in main queue
}
}
Run Code Online (Sandbox Code Playgroud)
然后我收到线程性能检查警告
以 QOS_CLASS_USER_INITIATED 运行的线程正在等待以 QOS_CLASS_DEFAULT 运行的较低 QoS 线程。研究避免优先级倒置的方法
我尝试打印它显示的外部队列的 qos
(lldb) print queue.qos
(Dispatch.DispatchQoS) $R0 = {
qosClass = unspecified //I think this should be default.
relativePriority = 0
}
Run Code Online (Sandbox Code Playgroud)
苹果文档错了?
class func global(qos: DispatchQoS.QoSClass = .default) -> DispatchQueue
Run Code Online (Sandbox Code Playgroud) 我正在使用Dispatch Queue加载图像,但如果我不希望它在某些时候加载所有图像,我不知道如何停止队列.
- (void) loadImageInBackgroundArr1:(NSMutableArray *)urlAndTagReference {
myQueue1 = dispatch_queue_create("com.razeware.imagegrabber.bgqueue", NULL);
for (int seriesCount = 0; seriesCount <[seriesIDArr count]; seriesCount++) {
for (int i = 0; i < [urlAndTagReference count]; i++) {
dispatch_async(myQueue1, ^(void) {
NSData *data0 = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:[urlAndTagReference objectAtIndex:i]]];
UIImage *image = [[UIImage alloc]initWithData:data0];
dispatch_sync(dispatch_get_main_queue(), ^(void) {
for (UIView * view in [OD_ImagesScrollView subviews]) {
if ([view isKindOfClass:[UIView class]]) {
for (id btn in [view subviews]) {
if ([btn isKindOfClass:[UIButton class]]) {
UIButton *imagesBtn = (UIButton *)btn; …Run Code Online (Sandbox Code Playgroud) 告诉我这是否有意义.这是一个iOS问题.
我看到它已经存在于主线程中的代码,但是代码会将各种UI代码分配给主线程的队列.布局,动画等
有人告诉我一些如何加快响应速度(例如,当推送视图控制器时,你会在那里调度其他UI操作,因此它不会阻止推送转换.
这没有意义,因为首先它是危险的,其次,它不保证UI代码何时运行(即使它可能以毫秒运行).我能看到的唯一好理由是它保证UI代码不会意外地在不同的线程中运行.
你们有什么感想?
当__weak self在我的块中使用在后台线程上运行的引用时,我是否只需要nil在开始时检查,或者__weak self在第一次nil测试通过后执行期间甚至可以变为nil ?我想从self块中访问一些ivars ,我需要在块执行时的最新值.
基本上,这是一个简单的项目,涉及一个表视图,该表视图根据从api的JSON解析的数据进行更新。我相信DispatchQueue.main.async并completed: @escaping () -> ()有事情做与更新/重装tableview中,但我不知道它是如何工作的。对于这两个功能的解释将不胜感激。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var heroes = [HeroStats]()
override func viewDidLoad() {
super.viewDidLoad()
fetchData {
print("Success")
}
}
func fetchData(completed: @escaping () -> ()) {
let jsonUrlString = "https://api.opendota.com/api/heroStats"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
if error == nil {
do {
let heroes …Run Code Online (Sandbox Code Playgroud) 我试图依次调用3个函数,但是每个函数都必须先完成才能运行下一个函数。每个函数都有一个完成处理程序,该处理程序在完成时调用另一个函数。在在线阅读了很多有关调度队列的信息后,尽管这可能是处理此问题的最佳方法,但是我当然可以正确地理解它。当我运行代码时,将依次调用每个函数,但在完成前一个函数时不会调用。在第一个功能中,我正在从Firebase下载图像,但是在下载图像之前调用了第二个功能。我已经在代码中删除了细节,但这是到目前为止。
typealias COMPLETION = () -> ()
let functionOne_completion = {
print("functionOne COMPLETED")
}
let functionTwo_completion = {
print("functionTwo COMPLETED")
}
let functionThree_completion = {
print("functionThree COMPLETED")
}
override func viewDidLoad() {
super.viewDidLoad()
let queue = DispatchQueue(label: "com.myApp.myQueue")
queue.sync {
functionOne(completion: functionOne_completion)
functionTwo(completion: functionTwo_completion)
functionThree(completion: functionThree_completion)
}
func functionOne(completion: @escaping COMPLETION) {
print("functionOne STARTED")
completion()
}
func functionTwo(completion: @escaping COMPLETION) {
print("functionTwo STARTED")
completion()
}
func functionThree(completion: @escaping COMPLETION) {
print("functionThree STARTED")
completion()
}
Run Code Online (Sandbox Code Playgroud) 我有3个线程从互联网上下载数据.
func thread1() {
DispatchQueue.global().async {
// do something from json
}
}
func thread2() {
DispatchQueue.global().async {
// do something from json
}
}
func thread3() {
DispatchQueue.global().async {
// download img
}
}
func finishFunction() {
print("Finish")
}
Run Code Online (Sandbox Code Playgroud)
我想在完成线程1,2和3后启动finishFunction函数.如何做到这一点?