ChatGPT解决这个技术问题 Extra ChatGPT

How to create dispatch queue in Swift 3

In Swift 2, I was able to create queue with the following code:

let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT)

But this doesn't compile in Swift 3.

What is the preferred way to write this in Swift 3?

Swift 4 has 3 extra params to create a serial queue. How to use them to create a serial queue? DispatchQueue.init(label: , qos: , attributes: , autoreleaseFrequency: , target: )
@nr5 Queues are serial by default, so it's sufficient to just use DispatchQueue(label: "your-label") for a serial queue. The extra params all have default values.

1
11 revs, 8 users 62%

Creating a concurrent queue

let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent)
concurrentQueue.sync {

}  

Create a serial queue

let serialQueue = DispatchQueue(label: "queuename")
serialQueue.sync { 

}

Get main queue asynchronously

DispatchQueue.main.async {

}

Get main queue synchronously

DispatchQueue.main.sync {

}

To get one of the background thread

DispatchQueue.global(qos: .background).async {

}

Xcode 8.2 beta 2:

To get one of the background thread

DispatchQueue.global(qos: .default).async {

}

DispatchQueue.global().async {
    // qos' default value is ´DispatchQoS.QoSClass.default`
}

If you want to learn about using these queues .See this answer


You can actually omit attributes: .serial when creating a serial queue: let serialQueue = DispatchQueue(label: "queuename").
In Xcode 8 beta 4 there is no .serial option so you have to create serial queue by omitting the .concurrent in attributes.
I need to access the DispatchQueue from Swift3 into objc but got the following error Cannot initialize a variable of type '__strong dispatch_queue_t' (aka 'NSObject *__strong') with an rvalue of type 'OS_dispatch_queue * _Nonnull' when doing dispatch_queue_t backgroundQueue = [SwiftClass Queue]; that is a static variable of DispatchQueue in swift
DispatchQueue.main.asynchronously(DispatchQueue.main) { self.mapView.add(self.mapPolyline) } in Swift 3.0 i've tried with DispatchQueue.global().asynchronously(DispatchQueue.main) { self.mapView.add(self.mapPolyline) } but both shows the same error as "value of type dispathQuoue has no member asynchronously"
from the OP's code, why does apple focus on using "com.swift3.imageQueue". I see that that the label has 3 parts. Why is that? what does each part stand for? I don't get the formatting
t
t1ser

Compiles under >=Swift 3. This example contains most of the syntax that we need.

QoS - new quality of service syntax

weak self - to disrupt retain cycles

if self is not available, do nothing

async global utility queue - for network query, does not wait for the result, it is a concurrent queue, the block (usually) does not wait when started. Exception for a concurrent queue could be, when its task limit has been previously reached, then the queue temporarily turns into a serial queue and waits until some previous task in that queue completes.

async main queue - for touching the UI, the block does not wait for the result, but waits for its slot at the start. The main queue is a serial queue.

Of course, you need to add some error checking to this...

DispatchQueue.global(qos: .utility).async { [weak self] () -> Void in

    guard let strongSelf = self else { return }

    strongSelf.flickrPhoto.loadLargeImage { loadedFlickrPhoto, error in

        if error != nil {
            print("error:\(error)")
        } else {
            DispatchQueue.main.async { () -> Void in
                activityIndicator.removeFromSuperview()
                strongSelf.imageView.image = strongSelf.flickrPhoto.largeImage
            }
        }
    }
}

When coding in Swift 3, get accustomed to condensing and deleting 30% of your previous code:-)
Thank you for [weak self] example!
It's better to guard that self is not nil at the top, so that none of the code is executed if it's nil, e.g., guard strongSelf = self else { return }.
@t1 Could you tell me where I can find the documentation for GCD written with code in Swift 3? I have only found the one written in Objective C. Someone here was pointing me to a video from WWDC, but I want to read the official documentation with examples in Swift 3 and there is no way to find it.
Do not use .global(qos: .background) for IO (network request). Use .global(qos: .default) or .global(qos: .utility) instead.
C
Cameron

Compiled in XCode 8, Swift 3 https://github.com/rpthomas/Jedisware

 @IBAction func tap(_ sender: AnyObject) {

    let thisEmail = "emailaddress.com"
    let thisPassword = "myPassword" 

    DispatchQueue.global(qos: .background).async {

        // Validate user input

        let result = self.validate(thisEmail, password: thisPassword)

        // Go back to the main thread to update the UI
        DispatchQueue.main.async {
            if !result
            {
                self.displayFailureAlert()
            }

        }
    }

}

C
Cosmin

Since the OP question has already been answered above I just want to add some speed considerations:

It makes a lot of difference what priority class you assign to your async function in DispatchQueue.global.

I don't recommend running tasks with the .background thread priority especially on the iPhone X where the task seems to be allocated on the low power cores.

Here is some real data from a computationally intensive function that reads from an XML file (with buffering) and performs data interpolation:

Device name / .background / .utility / .default / .userInitiated / .userInteractive

iPhone X: 18.7s / 6.3s / 1.8s / 1.8s / 1.8s iPhone 7: 4.6s / 3.1s / 3.0s / 2.8s / 2.6s iPhone 5s: 7.3s / 6.1s / 4.0s / 4.0s / 3.8s

Note that the data set is not the same for all devices. It's the biggest on the iPhone X and the smallest on the iPhone 5s.


Great info. Helped me
@Myk If the user has initiated and/or it's waiting for the results you should use .userInitiated or .userInteractive so any other operation is backtracked. In most other cases .default would be a good choice.
M
Mithra Singam

Update for swift 5

Serial Queue

let serialQueue = DispatchQueue.init(label: "serialQueue")
serialQueue.async {
    // code to execute
}

Concurrent Queue

let concurrentQueue = DispatchQueue.init(label: "concurrentQueue", qos: .background, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)

concurrentQueue.async {
// code to execute
}

From Apple documentation:

Parameters

label

A string label to attach to the queue to uniquely identify it in debugging tools such as Instruments, sample, stackshots, and crash reports. Because applications, libraries, and frameworks can all create their own dispatch queues, a reverse-DNS naming style (com.example.myqueue) is recommended. This parameter is optional and can be NULL.

qos

The quality-of-service level to associate with the queue. This value determines the priority at which the system schedules tasks for execution. For a list of possible values, see DispatchQoS.QoSClass.

attributes

The attributes to associate with the queue. Include the concurrent attribute to create a dispatch queue that executes tasks concurrently. If you omit that attribute, the dispatch queue executes tasks serially.

autoreleaseFrequency

The frequency with which to autorelease objects created by the blocks that the queue schedules. For a list of possible values, see DispatchQueue.AutoreleaseFrequency.

target

The target queue on which to execute blocks. Specify DISPATCH_TARGET_QUEUE_DEFAULT if you want the system to provide a queue that is appropriate for the current object.


A
Asfand Shabbir

I did this and this is especially important if you want to refresh your UI to show new data without user noticing like in UITableView or UIPickerView.

    DispatchQueue.main.async
 {
   /*Write your thread code here*/
 }

F
Fritz Gerald Moran
 DispatchQueue.main.async {
          self.collectionView?.reloadData() // Depends if you were populating a collection view or table view
    }


OperationQueue.main.addOperation {
    self.lblGenre.text = self.movGenre
}

//use Operation Queue if you need to populate the objects(labels, imageview, textview) on your viewcontroller


p
piet.t
   let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT) //Swift 2 version

   let concurrentQueue = DispatchQueue(label:"com.swift3.imageQueue", attributes: .concurrent) //Swift 3 version

I re-worked your code in Xcode 8, Swift 3 and the changes are marked in contrast to your Swift 2 version.


This looks cleaner than what I wrote. Thanks.
A
Amul4608

Swift 3

you want call some closure in swift code then you want to change in storyboard ya any type off change belong to view your application will crash

but you want to use dispatch method your application will not crash

async method

DispatchQueue.main.async 
{
 //Write code here                                   

}

sync method

DispatchQueue.main.sync 
{
     //Write code here                                  

}

I want to use async method in service calling time my code is DispatchQueue.main.async { let objstory1 = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController _ = self.navigationController?.pushViewController(objstory1, animated: false) }
Never use DispatchQueue.main.sync
Sync calls on the main queue will definitely cause problems.
B
Bhumika
DispatchQueue.main.async(execute: {

// write code

})

Serial Queue :

let serial = DispatchQueue(label: "Queuename")

serial.sync { 

 //Code Here

}

Concurrent queue :

 let concurrent = DispatchQueue(label: "Queuename", attributes: .concurrent)

concurrent.sync {

 //Code Here
}

This doesn't create a dispatch queue, it just puts you on the main queue after one tick through the run loop.
J
Joseph Mikko Manoza

For Swift 3

   DispatchQueue.main.async {
        // Write your code here
    }

@Moritz I couldn't agree more, unfortunately.
D
Deep
 let newQueue = DispatchQueue(label: "newname")
 newQueue.sync { 

 // your code

 }

t
tylernol

it is now simply:

let serialQueue = DispatchQueue(label: "my serial queue")

the default is serial, to get concurrent, you use the optional attributes argument .concurrent


You'd better update your answer by adding seiralQueue.async {}. @tylemol
H
Hitesh Chauhan
DispatchQueue.main.async(execute: {
   // code
})

Thank you for this code snippet, which may provide some immediate help. A proper explanation would greatly improve its educational value by showing why this is a good solution to the problem, and would make it more useful to future readers with similar, but not identical, questions. Please edit your answer to add explanation, and give an indication of what limitations and assumptions apply.
F
Forge

You can create dispatch queue using this code in swift 3.0

DispatchQueue.main.async
 {
   /*Write your code here*/
 }

   /* or */

let delayTime = DispatchTime.now() + Double(Int64(0.5 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)                   
DispatchQueue.main.asyncAfter(deadline: delayTime)
{
  /*Write your code here*/
}

Sorry, that's not creating a dispatch queue, that's accessing the main queue after one tick through the run loop.