<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Swift 5.5 新特性搶先看,async/await 將重磅來襲

          共 16413字,需瀏覽 33分鐘

           ·

          2021-06-06 16:57

          ????關(guān)注后回復(fù) “進群” ,拉你進程序員交流群????


          作者丨小集

          來源丨知識小集(ID:zsxjtip)


          再過一周的時間,WWDC21 就正式舉行了,如果不出意外的話,Swift 5.5 測試版也會在期間發(fā)布。早在 3 月 13 日,官方論壇就公布了 Swift 5.5 版本的發(fā)布計劃,并在 4 月 16 日拉出了 release/5.5 分支。經(jīng)過幾個月時間的準(zhǔn)備,從 Swift Evolution 中,我們能發(fā)現(xiàn) Swift 5.5 將為我們帶來許多期待已久的特性,如 async/await。我們今天就來簡單整理一下這些 可能 將在 Swift 5.5 中出現(xiàn)的新特性。

          SE-0291 包集合

          這個 proposal 旨在為 SwiftPM 添加對包集合的支持。包集合是包和相關(guān)元數(shù)據(jù)的列表,可以更輕松地發(fā)現(xiàn)特定用例的現(xiàn)有包。SwiftPM 將允許用戶訂閱這些集合,通過 swift package-collection 命令行界面搜索它們,并使 libSwiftPM 的任何客戶端都可以訪問它們的內(nèi)容。這個 proposal 關(guān)注于以命令行界面和包集合想著的配置數(shù)據(jù)格式。

          例如,list 命令將列出用戶配置的所有集合:

          $ swift package-collection list [--json]
          My organisation's packages - https://example.com/packages.json
          ...

          describe 命令顯示來自包本身的元數(shù)據(jù)。

          $ swift package-collection describe [--json] https://github.com/jpsim/yams
          Description: A sweet and swifty YAML parser built on LibYAML.
          Available Versions: 4.0.0, 3.0.0, ...
          Watchers: 14
          Readme: https://github.com/jpsim/Yams/blob/master/README.md
          Authors: @norio-nomura, @jpsim
          --------------------------------------------------------------
          Latest Version: 4.0.0
          Package Name: Yams
          Modules: Yams, CYaml
          Supported Platforms: iOS, macOS, Linux, tvOS, watchOS
          Supported Swift Versions: 5.3, 5.2, 5.1, 5.0
          License: MIT
          CVEs: ...

          https://github.com/apple/swift-evolution/blob/main/proposals/0291-package-collections.md

          SE-0293 將屬性包裝器擴展到函數(shù)和閉包參數(shù)

          Property Wrappers 用于抽象出常見的屬性訪問器模式,在 Swift 5.1 中引入。不過之前僅允許在局部變量和類型屬性上應(yīng)用屬性包裝器。而這個 proposal 的目標(biāo)是將屬性包裝器擴展到函數(shù)和閉包參數(shù)。

          例如,使用來自 PropertyKit 的驗證,我們可以將各種前提條件抽象到一個屬性包裝器中:

          @propertyWrapper
          struct Asserted<Value> {
          init(
          wrappedValue: Value,
          validation: Validation<Value>,
          ) { ... }

          var wrappedValue: Value { ... }
          }

          將 @Asserted 應(yīng)用于參數(shù)以對參數(shù)值斷言某些先決條件會很有用。例如,下面的代碼斷言傳遞給 quantity 參數(shù)的參數(shù)大于或等于1:

          func buy(
          @Asserted(.greaterOrEqual(1)) quantity: Int,
          of product: Product,
          ) { ... }

          https://github.com/apple/swift-evolution/blob/main/proposals/0293-extend-property-wrappers-to-function-and-closure-parameters.md

          SE-0295 有關(guān)聯(lián)值的枚舉的 Codable 合成

          在 SE-0166 中引入了 Codable,它支持合成類和結(jié)構(gòu)類型的 Encodable 和 Decodable 一致性,其中僅包含也符合各自協(xié)議的值。

          這個 proposal 將擴展對枚舉關(guān)聯(lián)值的一致性的自動合成的支持。

          如以下枚舉有關(guān)聯(lián)值:

          enum Command: Codable {
          case load(key: String)
          case store(key: String, value: Int)
          }

          將會被編碼為

          {
          "load": {
          "key": "MyKey"
          }
          }

          {
          "store": {
          "key": "MyKey",
          "value": 42
          }
          }

          編譯器將生成以下 CodingKeys 聲明:

          // contains keys for all cases of the enum
          enum CodingKeys: CodingKey {
          case load
          case store
          }

          // contains keys for all associated values of `case load`
          enum LoadCodingKeys: CodingKey {
          case key
          }

          // contains keys for all associated values of `case store`
          enum StoreCodingKeys: CodingKey {
          case key
          case value
          }

          https://github.com/apple/swift-evolution/blob/main/proposals/0295-codable-synthesis-for-enums-with-associated-values.md

          SE-0296 async/await

          現(xiàn)代 Swift 開發(fā)涉及大量使用閉包和完成處理程序的異步編程,但這些 API 都很難使用。當(dāng)使用許多異步操作、錯誤處理或異步調(diào)用之間的控制流變得復(fù)雜時,會讓問題變得很復(fù)雜。我們先看一個簡單的例子:

          // 一系列簡單的異步操作通常需要深度嵌套的閉包
          func processImageData1(completionBlock: (_ result: Image) -> Void) {
          loadWebResource("dataprofile.txt") { dataResource in
          loadWebResource("imagedata.dat") { imageResource in
          decodeImage(dataResource, imageResource) { imageTmp in
          dewarpAndCleanupImage(imageTmp) { imageResult in
          completionBlock(imageResult)
          }
          }
          }
          }
          }

          processImageData1 { image in
          display(image)
          }

          而這個提案則引入了一種語言擴展,大大簡化了這些操作,讓代碼更加自然而不易出錯。這種設(shè)計為 Swift 引入了一個協(xié)程模型。函數(shù)可以是 async,允許程序員使用正常的控制流機制編寫涉及異步操作的復(fù)雜邏輯。編譯器負(fù)責(zé)將異步函數(shù)轉(zhuǎn)換為一組合適的閉包和狀態(tài)機。實際上 async/await 語義早已是現(xiàn)代編程語言的標(biāo)配。我們來看看,async/await 如何讓代碼變得更加簡潔:

          func loadWebResource(_ path: String) async throws -> Resource
          func decodeImage(_ r1: Resource, _ r2: Resource) async throws -> Image
          func dewarpAndCleanupImage(_ i : Image) async throws -> Image

          func processImageData() async throws -> Image {
          let dataResource = try await loadWebResource("dataprofile.txt")
          let imageResource = try await loadWebResource("imagedata.dat")
          let imageTmp = try await decodeImage(dataResource, imageResource)
          let imageResult = try await dewarpAndCleanupImage(imageTmp)
          return imageResult
          }

          不過,這個 proposal 并不提供并發(fā),結(jié)構(gòu)化并發(fā)問題由另一個 proposal 引入,它將異步函數(shù)與并發(fā)執(zhí)行的任務(wù)相關(guān)聯(lián),并提供用于創(chuàng)建、查詢和取消任務(wù)的 API。

          https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md

          SE-0297 與 Objective-C 的并發(fā)互操作性

          在 Apple 平臺上,Swift 與 Objective-C 的混編與交互目前來講還是一個很大的課題。在 Objective-C 中,異步 API 隨處可見,在 iOS 14.0 SDK 中就包含了近 1000 個接受 completion 處理器的方法。例如以下 PassKit API 中的方法

          - (void)signData:(NSData *)signData 
          withSecureElementPass:(PKSecureElementPass *)secureElementPass
          completion:(void (^)(NSData *signedData, NSData *signature, NSError *error))completion;

          這些方法包括可以直接在 Swift 中調(diào)用的方法,可以在 Swift 定義的子類中覆蓋的方法,以及可以實現(xiàn)的協(xié)議中的方法。

          當(dāng)前,以上 Objective-C 函數(shù)在 Swift 中會被翻譯成以下函數(shù):

          @objc func sign(_ signData: Data, 
          using secureElementPass: PKSecureElementPass,
          completion: @escaping (Data?, Data?, Error?) -> Void
          )

          這個 proposal 旨在為 Swift 并發(fā)結(jié)構(gòu)與 Objective-C 之間提供互操作性,并實現(xiàn)以下目標(biāo):

          • 將 Objective-C 完成處理程序方法轉(zhuǎn)換為 Swift 中的 async 方法;

          • 允許將 Swift 中定義的 async 方法標(biāo)記為 @objc,在這種情況下,它們將作為完成處理程序方法導(dǎo)出;

          • 提供 Objective-C 屬性來控制如何將基于完成處理程序的 API 轉(zhuǎn)換為 asyncSwift 函數(shù)。

          基于這些假設(shè),以上 Objective-C 函數(shù)將會被翻譯為以下 async 函數(shù):

          @objc func sign(
          _ signData: Data,
          using secureElementPass: PKSecureElementPass
          )
          async throws -> (Data, Data)

          同時可以通過以下方式來調(diào)用:

          let (signedValue, signature) = try await passLibrary.sign(signData, using: pass)

          https://github.com/apple/swift-evolution/blob/main/proposals/0297-concurrency-objc.md

          SE-0298 Async/Await: 序列

          SE-0296 的 async/await 特性為 Swift 提供了更直觀的異步編程方式。而這個 proposal 的目標(biāo)是基于 async/await,以內(nèi)置的方式更直觀地編寫和使用隨時間返回多個值的函數(shù)。

          這個 proposal 主要由三個部分組成:

          • 表示異步值序列的協(xié)議的標(biāo)準(zhǔn)庫定義;

          • 編譯器支持在異步值序列上使用 for...in 語法;

          • 對異步值序列進行操作的常用函數(shù)的標(biāo)準(zhǔn)庫實現(xiàn)

          基于這個 proposal,迭代異步值序列像迭代同步值序列一樣簡單。一個示例用例是迭代文件中的行,如下所示:

          for try await line in myFile.lines() {
          // Do something with each line
          }

          為此,標(biāo)準(zhǔn)庫中定義了以下協(xié)議

          public protocol AsyncSequence {
          associatedtype AsyncIterator: AsyncIteratorProtocol where AsyncIterator.Element == Element
          associatedtype Element
          __consuming func makeAsyncIterator() -> AsyncIterator
          }

          public protocol AsyncIteratorProtocol {
          associatedtype Element
          mutating func next() async throws -> Element?
          }

          編譯器生成的代碼將允許在符合 AsyncSequence 的任何類型上使用for in循環(huán)。標(biāo)準(zhǔn)庫還將擴展協(xié)議以提供熟悉的通用算法。如以下示例:

          struct Counter : AsyncSequence {
          let howHigh: Int

          struct AsyncIterator : AsyncIteratorProtocol {
          let howHigh: Int
          var current = 1
          mutating func next() async -> Int? {
          // We could use the `Task` API to check for cancellation here and return early.
          guard current <= howHigh else {
          return nil
          }

          let result = current
          current += 1
          return result
          }
          }

          func makeAsyncIterator() -> AsyncIterator {
          return AsyncIterator(howHigh: howHigh)
          }
          }

          在調(diào)用端,則可以如下使用:

          for await i in Counter(howHigh: 3) {
          print(i)
          }

          /*
          Prints the following, and finishes the loop:
          1
          2
          3
          */



          for await i in Counter(howHigh: 3) {
          print(i)
          if i == 2 { break }
          }
          /*
          Prints the following:
          1
          2
          */

          https://github.com/apple/swift-evolution/blob/main/proposals/0298-asyncsequence.md

          SE-0299 在通用上下文中擴展靜態(tài)成員查找

          Swift 支持對具體類型的靜態(tài)成員查找,并通過類似枚舉的 . 語法來調(diào)用。例如,SwiftUI 中使用預(yù)定義的常用值作為靜態(tài)屬性擴展了 Font 和 Color 等類型。

          extension Font {
          public static let headline: Font
          public static let subheadline: Font
          public static let body: Font
          ...
          }

          extension Color {
          public static let red: Color
          public static let green: Color
          public static let blue: Color
          ...
          }

          可通過以下方式來調(diào)用:

          VStack {
          Text(item.title)
          .font(.headline)
          .foregroundColor(.primary)
          Text(item.subtitle)
          .font(.subheadline)
          .foregroundColor(.secondary)
          }

          不過,靜態(tài)成員查找目前存在一個問題:不支持泛型函數(shù)中的協(xié)議成員,所以沒有辦法使用 . 語法來調(diào)用,如 SwiftUI 定義了一個 toggleStyle 視圖裝飾器:

          extension View {
          public func toggleStyle<S: ToggleStyle>(_ style: S) -> some View
          }

          public protocol ToggleStyle {
          associatedtype Body: View
          func makeBody(configuration: Configuration) -> Body
          }

          public struct DefaultToggleStyle: ToggleStyle { ... }
          public struct SwitchToggleStyle: ToggleStyle { ... }
          public struct CheckboxToggleStyle: ToggleStyle { ... }

          目前的調(diào)用方式是,在使用 toggleStyle 修飾符時將具體類型以全名方式寫入 ToggleStyle:

          Toggle("Wi-Fi", isOn: $isWiFiEnabled)
          .toggleStyle(SwitchToggleStyle())

          而這個 proposal 的目標(biāo)是放寬對協(xié)議上訪問靜態(tài)成員的限制,讓泛型 API 具有更好的可讀性,即通過以下方式來調(diào)用:

          Toggle("Wi-Fi", isOn: $isWiFiEnabled)
          .toggleStyle(.switch)

          https://github.com/apple/swift-evolution/blob/main/proposals/0299-extend-generic-static-member-lookup.md

          SE-0300 異步任務(wù)與同步代碼接口

          異步 Swift 代碼需要能夠與使用諸如完成回調(diào)和委托方法之類的技術(shù)的現(xiàn)有同步代碼一起工作以響應(yīng)事件。異步任務(wù)可以將自己暫停,然后同步代碼可以捕獲并調(diào)用它們以響應(yīng)事件來恢復(fù)任務(wù)。

          標(biāo)準(zhǔn)庫將提供 API 來獲取當(dāng)前異步任務(wù)的延續(xù),這會掛起任務(wù),并產(chǎn)生一個值,同步代碼隨后可以通過該值使用句柄來恢復(fù)任務(wù)。例如

          func beginOperation(completion: (OperationResult) -> Void)

          我們可以通過掛起任務(wù)并在調(diào)用回調(diào)時使用其連續(xù)性將其恢復(fù)為異步接口,然后將傳遞給回調(diào)的參數(shù)轉(zhuǎn)換為異步函數(shù)的正常返回值:

          func operation() async -> OperationResult {
          // Suspend the current task, and pass its continuation into a closure
          // that executes immediately
          return await withUnsafeContinuation { continuation in
          // Invoke the synchronous callback-based API...
          beginOperation(completion: { result in
          // ...and resume the continuation when the callback is invoked
          continuation.resume(returning: result)
          })
          }
          }

          https://github.com/apple/swift-evolution/blob/main/proposals/0300-continuation.md

          SE-0304 結(jié)構(gòu)化并發(fā)

          async/await proposal 本向并沒有引入并發(fā)性:它只是忽略異步函數(shù)中的掛起點,它將以與同步函數(shù)基本相同的方式執(zhí)行。而這個 proposal 的目標(biāo)就是在 Swift 中引入結(jié)構(gòu)化并發(fā)的支持,并允許高效實現(xiàn)的模型來并發(fā)執(zhí)行異步代碼。

          例如以下一段準(zhǔn)備晚餐的代碼:

          func chopVegetables() async throws -> [Vegetable] { ... }
          func marinateMeat() async -> Meat { ... }
          func preheatOven(temperature: Double) async throws -> Oven { ... }

          // ...

          func makeDinner() async throws -> Meal {
          let veggies = try await chopVegetables()
          let meat = await marinateMeat()
          let oven = try await preheatOven(temperature: 350)

          let dish = Dish(ingredients: [veggies, meat])
          return try await oven.cook(dish, duration: .hours(3))
          }

          makeDinner 中的每個步驟都是異步操作,不過整個流程每個點都會暫停,直到當(dāng)前步驟完成。而為了更快地準(zhǔn)備好晚餐,我們需要同時執(zhí)行其中一些步驟,為此,可以將步驟分解為可以并行發(fā)生的不同任務(wù)。而這個 proposal 所提的結(jié)構(gòu)化并發(fā),就可以完成這種任務(wù)。proposal 中的概念很多,在此不詳細介紹。在使用結(jié)構(gòu)化并發(fā)對上述代碼改造后,代碼類似于以下:

          func makeDinner() async throws -> Meal {
          // Prepare some variables to receive results from our concurrent child tasks
          var veggies: [Vegetable]?
          var meat: Meat?
          var oven: Oven?

          enum CookingStep {
          case veggies([Vegetable])
          case meat(Meat)
          case oven(Oven)
          }

          // Create a task group to scope the lifetime of our three child tasks
          try await withThrowingTaskGroup(of: CookingStep.self)
          { group in
          group.async {
          try await .veggies(chopVegetables())
          }
          group.async {
          await .meat(marinateMeat())
          }
          group.async {
          try await .oven(preheatOven(temperature: 350))
          }

          for try await finishedStep in group {
          switch finishedStep {
          case .veggies(let v): veggies = v
          case .meat(let m): meat = m
          case .oven(let o): oven = o
          }
          }
          }

          // If execution resumes normally after `withTaskGroup`, then we can assume
          // that all child tasks added to the group completed successfully. That means
          // we can confidently force-unwrap the variables containing the child task
          // results here.
          let dish = Dish(ingredients: [veggies!, meat!])
          return try await oven!.cook(dish, duration: .hours(3))
          }

          https://github.com/apple/swift-evolution/blob/main/proposals/0304-structured-concurrency.md

          SE-0306 Actors

          Swift 并發(fā)模型旨在提供一種安全的編程模型,該模型可靜態(tài)檢測數(shù)據(jù)競爭和其他常見的并發(fā)錯誤。結(jié)構(gòu)化并發(fā)提議引入了一種定義并發(fā)任務(wù)的方法,并為函數(shù)和閉包提供了數(shù)據(jù)爭用安全性。該模型適用于許多常見的設(shè)計模式,包括諸如并行映射和并發(fā)回調(diào)模式之類,但僅限于使用由閉包捕獲的狀態(tài)。

          Swift 包含一些類,這些類提供了一種聲明可變狀態(tài)的機制,這些狀態(tài)可以在程序之間共享。然而,類很難在并發(fā)程序中正確使用,需要手動同步以避免數(shù)據(jù)競爭。我們希望提供使用共享可變狀態(tài)的功能,同時仍提供對數(shù)據(jù)競爭和其他常見并發(fā)錯誤的靜態(tài)檢測。

          actor 模型定義了稱為該角色的實體,非常適合此任務(wù)。Actor 允許聲明并發(fā)域中包含的狀態(tài)包,然后定義對其執(zhí)行操作的多個操作。每個 actor 都通過數(shù)據(jù)隔離來保護自己的數(shù)據(jù),從而確保即使在許多客戶端同時發(fā)出參與者請求的情況下,在給定的時間也只有一個線程可以訪問該數(shù)據(jù)。作為 Swift 并發(fā)模型的一部分,actor 提供了與結(jié)構(gòu)化并發(fā)相同的競爭和內(nèi)存安全屬性。

          actor 是一種引用類型,可保護對其可變狀態(tài)的訪問,并隨關(guān)鍵字 actor 一起引入:

          actor BankAccount {
          let accountNumber: Int
          var balance: Double

          init(accountNumber: Int, initialDeposit: Double) {
          self.accountNumber = accountNumber
          self.balance = initialDeposit
          }
          }

          像其他 Swift 類型一樣,actor 可以有初始化器,方法,屬性和下標(biāo)。它們可以擴展并符合協(xié)議,可以是通用的,也可以與通用一起使用。

          主要區(qū)別在于 actor 可以保護其狀態(tài)免受數(shù)據(jù)爭奪。這是 Swift 編譯器通過強制使用 actor 及其實例成員的方式受到一系列限制而靜態(tài)地強制實施的,統(tǒng)稱為 actor 隔離。

          https://github.com/apple/swift-evolution/blob/main/proposals/0306-actors.md

          SE-0307 允許互換使用 CGFloat 和 Double 類型

          Swift 首次發(fā)布時,CGFloat 的類型的使用就是一項挑戰(zhàn)。當(dāng)時,大多數(shù) iOS 設(shè)備仍為 32 位。諸如 CoreGraphics 之類的 SDK 提供的 API 在 32 位平臺上采用 32 位浮點值,在 64 位平臺上采用 64 位值。首次引入這些 API 時,在 32 位平臺上 32 位標(biāo)量算術(shù)速度更快,但是到 Swift 發(fā)行時,情況已不再如此:直到今天, 64 位標(biāo)量算術(shù)速度與 32 位一樣快。甚至在 32 位平臺上也是如此。之所以仍然保留了 32/64 位分割,主要是出于源和 ABI 穩(wěn)定性的原因。

          而這個 proposal 目標(biāo)是允許 Double 和 CGFloat 類型通過將一種類型透明轉(zhuǎn)換為另一種類型。

          https://github.com/apple/swift-evolution/blob/main/proposals/0307-allow-interchangeable-use-of-double-cgfloat-types.md

          SE-0308 #if 支持后綴成員表達式

          Swift 有條件編譯塊 #if ... #endif,它允許根據(jù)一個或多個編譯條件的值對代碼進行條件編譯。當(dāng)前,與 C 語言中的 #if 不同的是,每個子句的主體必須包含完整的語句。但是,在某些情況下,尤其是在結(jié)果生成器上下文中,出現(xiàn)了將 #if 應(yīng)用于部分表達式的需求。這個該 proposal 擴展了 #if ... #endif以便能夠包圍后綴成員表達式。

          例如當(dāng)前使用的如下代碼:

          VStack {
          let basicView = Text("something")
          #if os(iOS)
          basicView
          .iOSSpecificModifier()
          .commonModifier()
          #else
          basicView
          .commonModifier()
          #endif
          }

          可以改成以下這種方式

          VStack {
          Text("something")
          #if os(iOS)
          .iOSSpecificModifier()
          #endif
          .commonModifier()
          }

          https://github.com/apple/swift-evolution/blob/main/proposals/0308-postfix-if-config-expressions.md

          SE-0310 有效的只讀屬性

          異步函數(shù)旨在用于可能會或始終會在返回之前暫停執(zhí)行上下文切換的計算,但缺乏有效的只讀計算屬性和下標(biāo),因此這個 proposal 升級了 Swift 的只讀屬性以支持異步并單獨或一起拋出關(guān)鍵字,從而使它們明顯更靈活。

          為了說明這一點,我們可以創(chuàng)建一個 BundleFile 結(jié)構(gòu)體,嘗試將其內(nèi)容加載到應(yīng)用程序的資源包中。由于文件可能不存在,或者可能存在但由于某種原因而無法讀取,或者可能可讀但太大,因此需要花費一些時間才能讀取,因此我們可以將 contents 屬性標(biāo)記為異步拋出,如下所示:

          enum FileError: Error {
          case missing, unreadable
          }

          struct BundleFile {
          let filename: String

          var contents: String {
          get async throws {
          guard let url = Bundle.main.url(forResource: filename, withExtension: nil) else {
          throw FileError.missing
          }

          do {
          return try String(contentsOf: url)
          } catch {
          throw FileError.unreadable
          }
          }
          }
          }

          因為 content 既是異步的又是拋出的,所以我們在嘗試讀取它時必須使用 try await:

          func printHighScores() async throws {
          let file = BundleFile(filename: "highscores")
          try await print(file.contents)
          }

          https://github.com/apple/swift-evolution/blob/main/proposals/0310-effectful-readonly-properties.md

          SE-0316 全局 actors

          Actor 非常適合隔離實例數(shù)據(jù),但是當(dāng)需要隔離的數(shù)據(jù)分散在整個程序中,或者表示程序外部存在的某種狀態(tài)時,將所有代碼和數(shù)據(jù)都放入單個actor 實例中可能是不切實際的(例如,大型程序)甚至是不可能的(與那些假設(shè)無處不在的系統(tǒng)進行交互時)。

          global actors 的主要目標(biāo)是將 actor 模型應(yīng)用于只能由主線程訪問的狀態(tài)和操作。在應(yīng)用程序中,主線程通常負(fù)責(zé)執(zhí)行主要的事件處理循環(huán),該循環(huán)處理來自各種來源的事件并將其傳遞給應(yīng)用程序代碼。global actors 提供了一種機制,可以利用 actor 的角色來描述主線程,利用 Swift 的 actor 隔離模型來幫助正確使用主線程。

          @MainActor var globalTextSize: Int

          @MainActor func increaseTextSize() {
          globalTextSize += 2 // okay:
          }

          func notOnTheMainActor() async {
          globalTextSize = 12 // error: globalTextSize is isolated to MainActor
          increaseTextSize() // error: increaseTextSize is isolated to MainActor, cannot call synchronously
          await increaseTextSize() // okay: asynchronous call hops over to the main thread and executes there
          }

          https://github.com/apple/swift-evolution/blob/main/proposals/0316-global-actors.md

          SE-0317 async let bindings

          結(jié)構(gòu)化并發(fā)提供了一個范式,用于在有范圍的任務(wù)組中生成并發(fā)子任務(wù),建立定義明確的任務(wù)層次結(jié)構(gòu),從而可以透明地處理并發(fā)管理的取消,錯誤傳播,優(yōu)先級管理和其他棘手的細節(jié)。

          這個 proposal 旨在使用類似于 let 綁定的輕量級語法,使生成子任務(wù)的常規(guī)任務(wù)異步運行,并將最終結(jié)果傳遞給父任務(wù)。

          還是以午餐為例,使用 async let,那么代碼看起來是下面這種:

          func makeDinner() async throws -> Meal {
          async let veggies = chopVegetables()
          async let meat = marinateMeat()
          async let oven = preheatOven(temperature: 350)

          let dish = Dish(ingredients: await [try veggies, meat])
          return try await oven.cook(dish, duration: .hours(3))
          }

          https://github.com/apple/swift-evolution/blob/main/proposals/0317-async-let.md

          小結(jié)

          這里只是整理了部分在 Swift 5.5 中實現(xiàn)的 proposal 或者是在當(dāng)前 main 快照中審核的 proposal。可以看到 async/await 及一些異步模型將會是 Swift 5.5 的重點內(nèi)容。當(dāng)然,最終 Swift 5.5 會新增哪些特性,還需要等最后的結(jié)果。也許 Swift 團隊會將一些新特性放到 Swift 6 中發(fā)布。讓我們期待一下 WWDC21 吧。

          -End-

          最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!

          點擊??卡片,關(guān)注后回復(fù)【面試題】即可獲取

          在看點這里好文分享給更多人↓↓

          瀏覽 61
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品无码一区二区三区无毛 | 亚洲无码高清视频在线 | 成人精品操BB视频 | 99成人精品视频 | 影音先锋最新av资源 |