<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 將重磅來(lái)襲

          共 15909字,需瀏覽 32分鐘

           ·

          2021-06-01 13:41

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

          SE-0291 包集合

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

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

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

          describe 命令顯示來(lái)自包本身的元數(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 將屬性包裝器擴(kuò)展到函數(shù)和閉包參數(shù)

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

          例如,使用來(lái)自 PropertyKit 的驗(yàn)證,我們可以將各種前提條件抽象到一個(gè)屬性包裝器中:

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

          var wrappedValue: Value { ... }
          }

          將 @Asserted 應(yīng)用于參數(shù)以對(duì)參數(shù)值斷言某些先決條件會(huì)很有用。例如,下面的代碼斷言傳遞給 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,它支持合成類(lèi)和結(jié)構(gòu)類(lèi)型的 Encodable 和 Decodable 一致性,其中僅包含也符合各自協(xié)議的值。

          這個(gè) proposal 將擴(kuò)展對(duì)枚舉關(guān)聯(lián)值的一致性的自動(dòng)合成的支持。

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

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

          將會(huì)被編碼為

          {
          "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 開(kāi)發(fā)涉及大量使用閉包和完成處理程序的異步編程,但這些 API 都很難使用。當(dāng)使用許多異步操作、錯(cuò)誤處理或異步調(diào)用之間的控制流變得復(fù)雜時(shí),會(huì)讓問(wèn)題變得很復(fù)雜。我們先看一個(gè)簡(jiǎn)單的例子:

          // 一系列簡(jiǎn)單的異步操作通常需要深度嵌套的閉包
          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)
          }

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

          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
          }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

          同時(shí)可以通過(guò)以下方式來(lái)調(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 提供了更直觀(guān)的異步編程方式。而這個(gè) proposal 的目標(biāo)是基于 async/await,以?xún)?nèi)置的方式更直觀(guān)地編寫(xiě)和使用隨時(shí)間返回多個(gè)值的函數(shù)。

          這個(gè) proposal 主要由三個(gè)部分組成:

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

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

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

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

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

          為此,標(biāo)準(zhǔn)庫(kù)中定義了以下協(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 的任何類(lèi)型上使用for in循環(huán)。標(biāo)準(zhǔn)庫(kù)還將擴(kuò)展協(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 在通用上下文中擴(kuò)展靜態(tài)成員查找

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

          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
          ...
          }

          可通過(guò)以下方式來(lái)調(diào)用:

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

          不過(guò),靜態(tài)成員查找目前存在一個(gè)問(wèn)題:不支持泛型函數(shù)中的協(xié)議成員,所以沒(méi)有辦法使用 . 語(yǔ)法來(lái)調(diào)用,如 SwiftUI 定義了一個(gè) 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 修飾符時(shí)將具體類(lèi)型以全名方式寫(xiě)入 ToggleStyle:

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

          而這個(gè) proposal 的目標(biāo)是放寬對(duì)協(xié)議上訪(fǎng)問(wèn)靜態(tài)成員的限制,讓泛型 API 具有更好的可讀性,即通過(guò)以下方式來(lái)調(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)和委托方法之類(lèi)的技術(shù)的現(xiàn)有同步代碼一起工作以響應(yīng)事件。異步任務(wù)可以將自己暫停,然后同步代碼可以捕獲并調(diào)用它們以響應(yīng)事件來(lái)恢復(fù)任務(wù)。

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

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

          我們可以通過(guò)掛起任務(wù)并在調(diào)用回調(diào)時(shí)使用其連續(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 本向并沒(méi)有引入并發(fā)性:它只是忽略異步函數(shù)中的掛起點(diǎn),它將以與同步函數(shù)基本相同的方式執(zhí)行。而這個(gè) proposal 的目標(biāo)就是在 Swift 中引入結(jié)構(gòu)化并發(fā)的支持,并允許高效實(shí)現(xiàn)的模型來(lái)并發(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 中的每個(gè)步驟都是異步操作,不過(guò)整個(gè)流程每個(gè)點(diǎn)都會(huì)暫停,直到當(dāng)前步驟完成。而為了更快地準(zhǔn)備好晚餐,我們需要同時(shí)執(zhí)行其中一些步驟,為此,可以將步驟分解為可以并行發(fā)生的不同任務(wù)。而這個(gè) proposal 所提的結(jié)構(gòu)化并發(fā),就可以完成這種任務(wù)。proposal 中的概念很多,在此不詳細(xì)介紹。在使用結(jié)構(gòu)化并發(fā)對(duì)上述代碼改造后,代碼類(lèi)似于以下:

          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)檢測(cè)數(shù)據(jù)競(jìng)爭(zhēng)和其他常見(jiàn)的并發(fā)錯(cuò)誤。結(jié)構(gòu)化并發(fā)提議引入了一種定義并發(fā)任務(wù)的方法,并為函數(shù)和閉包提供了數(shù)據(jù)爭(zhēng)用安全性。該模型適用于許多常見(jiàn)的設(shè)計(jì)模式,包括諸如并行映射和并發(fā)回調(diào)模式之類(lèi),但僅限于使用由閉包捕獲的狀態(tài)。

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

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

          actor 是一種引用類(lèi)型,可保護(hù)對(duì)其可變狀態(tài)的訪(fǎng)問(wèn),并隨關(guān)鍵字 actor 一起引入:

          actor BankAccount {
          let accountNumber: Int
          var balance: Double

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

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

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

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

          SE-0307 允許互換使用 CGFloat 和 Double 類(lèi)型

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

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

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

          SE-0308 #if 支持后綴成員表達(dá)式

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

          例如當(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ù)旨在用于可能會(huì)或始終會(huì)在返回之前暫停執(zhí)行上下文切換的計(jì)算,但缺乏有效的只讀計(jì)算屬性和下標(biāo),因此這個(gè) proposal 升級(jí)了 Swift 的只讀屬性以支持異步并單獨(dú)或一起拋出關(guān)鍵字,從而使它們明顯更靈活。

          為了說(shuō)明這一點(diǎn),我們可以創(chuàng)建一個(gè) BundleFile 結(jié)構(gòu)體,嘗試將其內(nèi)容加載到應(yīng)用程序的資源包中。由于文件可能不存在,或者可能存在但由于某種原因而無(wú)法讀取,或者可能可讀但太大,因此需要花費(fèi)一些時(shí)間才能讀取,因此我們可以將 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
          }
          }
          }
          }

          因?yàn)?content 既是異步的又是拋出的,所以我們?cè)趪L試讀取它時(shí)必須使用 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í)例數(shù)據(jù),但是當(dāng)需要隔離的數(shù)據(jù)分散在整個(gè)程序中,或者表示程序外部存在的某種狀態(tài)時(shí),將所有代碼和數(shù)據(jù)都放入單個(gè)actor 實(shí)例中可能是不切實(shí)際的(例如,大型程序)甚至是不可能的(與那些假設(shè)無(wú)處不在的系統(tǒng)進(jìn)行交互時(shí))。

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

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

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

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

          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 中實(shí)現(xiàn)的 proposal 或者是在當(dāng)前 main 快照中審核的 proposal??梢钥吹?async/await 及一些異步模型將會(huì)是 Swift 5.5 的重點(diǎn)內(nèi)容。當(dāng)然,最終 Swift 5.5 會(huì)新增哪些特性,還需要等最后的結(jié)果。也許 Swift 團(tuán)隊(duì)會(huì)將一些新特性放到 Swift 6 中發(fā)布。讓我們期待一下 WWDC21 吧。



          推薦閱讀

          ?  為 iPad 部署基于 VS Code 的遠(yuǎn)程開(kāi)發(fā)環(huán)境
          ?  “And away we code. ” WWDC21 超 200 個(gè) Session 等著你
          ?  Google 正式發(fā)布 Fuchsia OS,F(xiàn)lutter 集成尚存問(wèn)題
          ?  京東APP訂單業(yè)務(wù)Swift優(yōu)化總結(jié)


          就差您點(diǎn)一下了 ??????

          瀏覽 77
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  日韩三级片免费观看 | 欧美性交手机在线 | 东京热福利视频 | 超碰国产操逼 | 99精品视频在线免费观看 |