如何在Swift 3、Swift 4和其他版本中分派_sync、dispatch_async、dispatch_after等?

[英]How do I dispatch_sync, dispatch_async, dispatch_after, etc in Swift 3, Swift 4, and beyond?


I have lots of code in Swift 2.x (or even 1.x) projects that looks like this:

我有很多Swift 2的代碼。x(甚至1。x)項目是這樣的:

// Move to a background thread to do some long running work
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
    let image = self.loadOrGenerateAnImage()
    // Bounce back to the main thread to update the UI
    dispatch_async(dispatch_get_main_queue()) {
        self.imageView.image = image
    }
}

Or stuff like this to delay execution:

或者像這樣拖延執行的東西:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
    print("test")
}

Or any of all kinds of other uses of the Grand Central Dispatch API...

或任何其他用途的大中央調度API…

Now that I've opened my project in Xcode 8 (beta) for Swift 3, I get all kinds of errors. Some of them offer to fix my code, but not all of the fixes produce working code. What do I do about this?

現在我已經在Xcode 8 (beta)中為Swift 3打開了我的項目,我得到了各種各樣的錯誤。其中一些提供修復我的代碼,但不是所有的修復都會產生工作代碼。我該怎么辦?

5 个解决方案

#1


292  

Since the beginning, Swift has provided some facilities for making ObjC and C more Swifty, adding more with each version. Now, in Swift 3, the new "import as member" feature lets frameworks with certain styles of C API -- where you have a data type that works sort of like a class, and a bunch of global functions to work with it -- act more like Swift-native APIs. The data types import as Swift classes, their related global functions import as methods and properties on those classes, and some related things like sets of constants can become subtypes where appropriate.

從一開始,Swift就為ObjC和C提供了一些便利,每個版本都增加了更多內容。現在,在Swift 3中,新的“作為成員的導入”特性讓具有特定風格的C API框架(其中有一種類似類的數據類型,以及一組用於處理它的全局函數)更像Swift本地API。數據類型作為Swift類導入,它們的相關全局函數作為這些類的方法和屬性導入,以及一些相關的東西,如常量集,可以在適當的情況下成為子類型。

In Xcode 8 / Swift 3 beta, Apple has applied this feature (along with a few others) to make the Dispatch framework much more Swifty. (And Core Graphics, too.) If you've been following the Swift open-source efforts, this isn't news, but now is the first time it's part of Xcode.

在Xcode 8 / Swift 3 beta版中,蘋果應用了這個特性(以及其他一些特性),使分派框架更加敏捷。(和核心圖形。)如果您一直在遵循Swift開源的努力,這不是新聞,但現在是第一次它是Xcode的一部分。

Your first step on moving any project to Swift 3 should be to open it in Xcode 8 and choose Edit > Convert > To Current Swift Syntax... in the menu. This will apply (with your review and approval) all of the changes at once needed for all the renamed APIs and other changes. (Often, a line of code is affected by more than one of these changes at once, so responding to error fix-its individually might not handle everything right.)

將任何項目轉移到Swift 3的第一步應該是在Xcode 8中打開它,並選擇Edit >將>轉換為當前的Swift語法……在菜單。這將應用(經過您的審查和批准)所有重命名的api和其他更改所需的所有更改。(通常情況下,一行代碼會同時受到多個更改的影響,因此對錯誤進行響應可能不能正確處理所有問題)。

The result is that the common pattern for bouncing work to the background and back now looks like this:

結果是,將工作返回背景的常見模式如下:

// Move to a background thread to do some long running work
DispatchQueue.global(qos: .userInitiated).async {
    let image = self.loadOrGenerateAnImage()
    // Bounce back to the main thread to update the UI
    DispatchQueue.main.async {
        self.imageView.image = image
    }
}

Note we're using .userInitiated instead of one of the old DISPATCH_QUEUE_PRIORITY constants. Quality of Service (QoS) specifiers were introduced in OS X 10.10 / iOS 8.0, providing a clearer way for the system to prioritize work and deprecating the old priority specifiers. See Apple's docs on background work and energy efficiency for details.

注意,我們使用的是. userinitiative,而不是一個舊的DISPATCH_QUEUE_PRIORITY常量。在OS X 10.10 / ios8.0中引入了服務質量(QoS)說明,為系統優化工作和對舊的優先級說明提供了更清晰的方法。詳情請參閱蘋果公司關於背景工作和能源效率的文檔。

By the way, if you're keeping your own queues to organize work, the way to get one now looks like this (notice that DispatchQueueAttributes is an OptionSet, so you use collection-style literals to combine options):

順便說一下,如果您要保持自己的隊列來組織工作,那么獲得一個隊列的方法現在看起來是這樣的(注意DispatchQueueAttributes是一個選項集,所以您使用集合樣式的文字來組合選項):

class Foo { 
    let queue = DispatchQueue(label: "com.example.my-serial-queue",
                           attributes: [.serial, .qosUtility])
    func doStuff() {
        queue.async {
            print("Hello World")
        }
    }
}

Using dispatch_after to do work later? That's a method on queues, too, and it takes a DispatchTime, which has operators for various numeric types so you can just add whole or fractional seconds:

使用dispatch_after進行后續工作?這也是一個關於隊列的方法,它需要一個調度時間,它有各種數字類型的操作符,所以你可以只添加整秒或小數秒:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // in half a second...
    print("Are we there yet?")
}

You can find your way around the new Dispatch API by opening its interface in Xcode 8 -- use Open Quickly to find the Dispatch module, or put a symbol (like DispatchQueue) in your Swift project/playground and command-click it, then brouse around the module from there. (You can find the Swift Dispatch API in Apple's spiffy new API Reference website and in-Xcode doc viewer, but it looks like the doc content from the C version hasn't moved into it just yet.)

通過在Xcode 8中打開它的接口,您可以找到新的分派API——使用Open快速找到分派模塊,或者在Swift項目/游樂場中放置一個符號(如DispatchQueue),然后單擊它,然后在模塊周圍啟動。(你可以在蘋果最新的API參考網站和in- xcode doc查看器中找到Swift Dispatch API,但看起來C版本的doc內容還沒有進入。)

See the Migration Guide for more tips.

請參閱遷移指南以獲得更多提示。

#2


116  

in xcode 8 beta 4 does not work.. Use:

在xcode 8 beta 4中不工作。使用:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    print("Are we there yet?")
}

for async two ways:

異步兩種方式:

DispatchQueue.main.async {
    print("Async1")
}

DispatchQueue.main.async( execute: {
    print("Async2")
})

#3


52  

This one is good example for Swift 4 about async:

這是關於異步的一個很好的例子:

DispatchQueue.global(qos: .background).async {
    // Background Thread
    DispatchQueue.main.async {
        // Run UI Updates or call completion block
    }
}

#4


33  

in xcode8 use:

在xcode8使用:

DispatchQueue.global(qos: .userInitiated).async { }

#5


12  

Swift 4

Main and Background Queues

主要和背景隊列

let main = DispatchQueue.main
let background = DispatchQueue.global()
let helper = DispatchQueue(label: "another_thread") 

Working with async and sync threads!

使用異步和同步線程!

 background.async { //async tasks here } 
 background.sync { //sync tasks here } 

Async threads will work along with the main thread.

異步線程將與主線程一起工作。

Sync threads will block the main thread while executing.

同步線程將在執行時阻塞主線程。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2016/06/14/72f3f2f95424c41ed8d84049603a070.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com