成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Sendable 和 @Sendable 閉包代碼實例詳解

移動開發(fā) iOS
Sendable協(xié)議和閉包表明那些傳遞的值的公共API是否線程安全的向編譯器傳遞了值。當沒有公共修改器、有內(nèi)部鎖定系統(tǒng)或修改器實現(xiàn)了與值類型一樣的復(fù)制寫入時,公共API可以安全地跨并發(fā)域使用。

Sendable? 和 @Sendable 是 Swift 5.5 中的并發(fā)修改的一部分,解決了結(jié)構(gòu)化的并發(fā)結(jié)構(gòu)體和執(zhí)行者消息之間傳遞的類型檢查的挑戰(zhàn)性問題。

應(yīng)該在什么時候使用 Sendable?

Sendable協(xié)議和閉包表明那些傳遞的值的公共API是否線程安全的向編譯器傳遞了值。當沒有公共修改器、有內(nèi)部鎖定系統(tǒng)或修改器實現(xiàn)了與值類型一樣的復(fù)制寫入時,公共API可以安全地跨并發(fā)域使用。

標準庫中的許多類型已經(jīng)支持了Sendable協(xié)議,消除了對許多類型添加一致性的要求。由于標準庫的支持,編譯器可以為你的自定義類型創(chuàng)建隱式一致性。

例如,整型支持該協(xié)議:

extension Int: Sendable {}

一旦我們創(chuàng)建了一個具有 Int 類型的單一屬性的值類型結(jié)構(gòu)體,我們就隱式地得到了對 Sendable 協(xié)議的支持。

struct Article {
var views: Int
}

與此同時,同樣的 Article 內(nèi)容的類,將不會有隱式遵守該協(xié)議:

class Article {
var views: Int
}

類不符合要求,因為它是一個引用類型,因此可以從其他并發(fā)域變異。換句話說,該類文章(Article)的傳遞不是線程安全的,所以編譯器不能隱式地將其標記為遵守Sendable協(xié)議。

使用泛型和枚舉時的隱式一致性

很好理解的是,如果泛型不符合Sendable協(xié)議,編譯器就不會為泛型添加隱式的一致性。

struct Container<Value> {
var child: Value
}

然而,如果我們將協(xié)議要求添加到我們的泛型中,我們將得到隱式支持:

struct Container<Value: Sendable> {
var child: Value
}

對于有關(guān)聯(lián)值的枚舉也是如此:

圖片

如果枚舉值們不符合 Sendable 協(xié)議,隱式的Sendable協(xié)議一致性就不會起作用。

你可以看到,我們自動從編譯器中得到一個錯誤:

Associated value ‘loggedIn(name:)’ of ‘Sendable’-conforming enum ‘State’ has non-sendable type ‘(name: NSAttributedString)’。

我們可以通過使用一個值類型String來解決這個錯誤,因為它已經(jīng)符合Sendable。

enum State: Sendable {
case loggedOut
case loggedIn(name: String)
}

從線程安全的實例中拋出錯誤

同樣的規(guī)則適用于想要符合Sendable的錯誤類型。

struct ArticleSavingError: Error {
var author: NonFinalAuthor
}

extension ArticleSavingError: Sendable { }

由于作者不是不變的(non-final),而且不是線程安全的(后面會詳細介紹),我們會遇到以下錯誤:

Stored property ‘a(chǎn)uthor’ of ‘Sendable’-conforming struct ‘ArticleSavingError’ has non-sendable type ‘NonFinalAuthor’。

你可以通過確保ArticleSavingError?的所有成員都符合Sendable協(xié)議來解決這個錯誤。

隱式一致性消除了很多我們需要自己為Sendable協(xié)議添加一致性的情況。然而,在有些情況下,我們知道我們的類型是線程安全的,但是編譯器并沒有為我們添加隱式一致性。

常見的例子是被標記為不可變和內(nèi)部具有鎖定機制的類:

final class User: Sendable {
let name: String

init(name: String) { self.name = name }
}

你需要用@unchecked屬性來標記可變類,以表明我們的類由于內(nèi)部鎖定機制所以是線程安全的:

extension DispatchQueue {
static let userMutatingLock = DispatchQueue(label: "person.lock.queue")
}

final class MutableUser: @unchecked Sendable {
private var name: String = ""

func updateName(_ name: String) {
DispatchQueue.userMutatingLock.sync {
self.name = name
}
}
}

Sendable協(xié)議的一致性必須發(fā)生在同一個源文件中,以確保編譯器檢查所有可見成員的線程安全。

例如,你可以在例如 Swift package這樣的模塊中定義以下類型:

public struct Article {
internal var title: String
}

Article 是公開的,而標題title是內(nèi)部的,在模塊外不可見。因此,編譯器不能在源文件之外應(yīng)用Sendable一致性,因為它對標題屬性不可見,即使標題使用的是遵守Sendable協(xié)議的String類型。

同樣的問題發(fā)生在我們想要使一個可變的非最終類遵守Sendable協(xié)議時:

圖片

可變的非最終類無法遵守 Sendable 協(xié)議。

由于該類是非最終的,我們無法符合Sendable?協(xié)議的要求,因為我們不確定其他類是否會繼承User?的非Sendable成員。因此,我們會遇到以下錯誤:

Non-final class ‘User’ cannot conform to ?Sendable?; use ?@unchecked Sendable?。

正如你所看到的,編譯器建議使用@unchecked Sendable?。我們可以把這個屬性添加到我們的User類中,并擺脫這個錯誤:

class User: @unchecked Sendable {
let name: String

init(name: String) { self.name = name }
}

然而,這確實要求我們無論何時從User繼承,都要確保它是線程安全的。由于我們給自己和同事增加了額外的責任,我不鼓勵使用這個屬性,建議使用組合、最終類或值類型來實現(xiàn)我們的目的。

函數(shù)可以跨并發(fā)域傳遞,因此也需要可發(fā)送的一致性。然而,函數(shù)不能符合協(xié)議,所以Swift引入了@Sendable屬性。你可以傳遞的函數(shù)的例子是全局函數(shù)聲明、閉包和訪問器,如getters和setters。

SE-302的部分動機是執(zhí)行盡可能少的同步。

我們希望這樣一個系統(tǒng)中的絕大多數(shù)代碼都是無同步的。

使用@Sendable屬性,我們將告訴編譯器,他不需要額外的同步,因為閉包中所有捕獲的值都是線程安全的。一個典型的例子是在Actor isolation中使用閉包。

actor ArticlesList {
func filteredArticles(_ isIncluded: @Sendable (Article) -> Bool) async -> [Article] {

}
}

如果你用非 Sendabel 類型的閉包,我們會遇到一個錯誤:

let listOfArticles = ArticlesList()
var searchKeyword: NSAttributedString? = NSAttributedString(string: "keyword")
let filteredArticles = await listOfArticles.filteredArticles { article in
guard let searchKeyword = searchKeyword else { return false }
return article.title == searchKeyword.string
}

當然,我們可以通過使用一個普通的String來快速解決這種情況,但它展示了編譯器如何幫助我們執(zhí)行線程安全。

Xcode 14 允許您通過 SWIFT_STRICT_CONCURRENCY 構(gòu)建設(shè)置啟用嚴格的并發(fā)性檢查。

圖片

啟用嚴格的并發(fā)性檢查,以修復(fù) Sendable 的符合性。

這個構(gòu)建設(shè)置控制編譯器對Sendable和actor-isolation檢查的執(zhí)行水平:

  • Minimal : 編譯器將只診斷明確標有Sendable一致性的實例,并等同于Swift 5.5和5.6的行為。不會有任何警告或錯誤。
  • Targeted:  強制執(zhí)行Sendable約束,并對你所有采用async/await等并發(fā)的代碼進行actor-isolation檢查。編譯器還將檢查明確采用Sendable的實例。這種模式試圖在與現(xiàn)有代碼的兼容性和捕捉潛在的數(shù)據(jù)競賽之間取得平衡。
  • Complete:  匹配預(yù)期的 Swift 6語義,以檢查和消除數(shù)據(jù)競賽。這種模式檢查其他兩種模式所做的一切,并對你項目中的所有代碼進行這些檢查。

嚴格的并發(fā)檢查構(gòu)建設(shè)置有助于 Swift 向數(shù)據(jù)競賽安全邁進。與此構(gòu)建設(shè)置相關(guān)的每一個觸發(fā)的警告都可能表明你的代碼中存在潛在的數(shù)據(jù)競賽。因此,必須考慮啟用嚴格并發(fā)檢查來驗證你的代碼。

Enabling strict concurrency in Xcode 14

你會得到的警告數(shù)量取決于你在項目中使用并發(fā)的頻率。對于Stock Analyzer,我有大約17個警告需要解決:

圖片

并發(fā)相關(guān)的警告,表明潛在的數(shù)據(jù)競賽。

這些警告可能讓人望而生畏,但利用本文的知識,你應(yīng)該能夠擺脫大部分警告,防止數(shù)據(jù)競賽的發(fā)生。然而,有些警告是你無法控制的,因為是外部模塊觸發(fā)了它們。在我的例子中,我有一個與SWHighlight有關(guān)的警告,它不符合Sendable,而蘋果在他們的SharedWithYou框架中定義了它。

在上述SharedWithYou框架的例子中,最好是等待庫的所有者添加Sendable支持。在這種情況下,這就意味著要等待蘋果公司為SWHighlight實例指明Sendable的一致性。對于這些庫,你可以通過使用@preconcurrency屬性來暫時禁用Sendable警告:?

@preconcurrency import SharedWithYou

重要的是要明白,我們并沒有解決這些警告,而只是禁用了它們。來自這些庫的代碼仍然有可能發(fā)生數(shù)據(jù)競賽。如果你正在使用這些框架的實例,你需要考慮實例是否真的是線程安全的。一旦你使用的框架被更新為Sendable的一致性,你可以刪除@preconcurrency屬性,并修復(fù)可能觸發(fā)的警告。

責任編輯:姜華 來源: Swift社區(qū)
相關(guān)推薦

2023-02-08 09:01:42

Swift元素流

2011-07-27 16:55:12

Objective-c 閉包

2017-09-14 13:55:57

JavaScript

2024-01-22 09:51:32

Swift閉包表達式尾隨閉包

2009-10-26 09:41:26

PHP5.3閉包特性

2022-12-02 09:02:36

Swift代碼異步

2021-02-21 16:21:19

JavaScript閉包前端

2009-09-02 17:12:06

C#關(guān)機代碼

2021-12-06 07:15:48

Javascript作用域閉包

2020-10-14 15:15:28

JavaScript(

2011-05-25 14:48:33

Javascript閉包

2009-07-22 07:43:00

Scala閉包

2013-05-02 09:44:57

PHP閉包

2016-10-27 19:26:47

Javascript閉包

2019-11-07 21:51:18

閉包前端函數(shù)

2023-11-02 08:53:26

閉包Python

2024-12-19 11:00:00

TCP網(wǎng)絡(luò)通信粘包

2022-11-21 09:01:00

Swift并發(fā)結(jié)構(gòu)

2009-05-13 14:15:09

PHP 5.3閉包匿名函數(shù)

2016-09-14 09:20:05

JavaScript閉包Web
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美激情在线精品一区二区三区 | 亚洲36d大奶网 | 国产91丝袜在线播放 | 日韩精品一区二区三区在线 | 国产精品久久久久久久久久久免费看 | 黄色一级在线播放 | 欧美精品一区在线发布 | 欧美亚洲视频在线观看 | 亚洲一区二区三区免费在线观看 | 精品日韩电影 | 欧美精品啪啪 | 自拍偷拍第一页 | 久久久久久久久久久丰满 | 久久国产视频一区 | 精品国产青草久久久久96 | 黄色片视频网站 | 成人动慢 | 欧美精品久久久久 | 午夜视频免费在线观看 | 日韩欧美国产精品 | 久久精品二区亚洲w码 | 三级在线视频 | 午夜精品久久 | 国产小视频在线 | 国产精品免费福利 | 亚洲久久一区 | 日韩视频a | 日韩中文字幕 | 成人午夜精品 | 日韩中文一区二区三区 | 中文字幕二区三区 | 成人精品一区二区三区中文字幕 | 久久精品一区 | 亚洲国产精品网站 | 久久综合香蕉 | 欧美色999 | 欧美美女一区二区 | 中文字幕在线免费视频 | 亚洲手机视频在线 | av一级久久 | 日本特黄a级高清免费大片 国产精品久久性 |