最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Swift?并發(fā)修改Sendable?閉包實(shí)例詳解

 更新時(shí)間:2022年10月13日 09:32:48   作者:Swift社區(qū)  
這篇文章主要為大家介紹了Swift?并發(fā)修改Sendable?閉包實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

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

使用 Sendable

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

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

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

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

extension Int: Sendable {}

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

// 隱式地遵守了 Sendable 協(xié)議
struct Article {
    var views: Int
}

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

// 不會(huì)隱式的遵守 Sendable 協(xié)議
class Article {
    var views: Int
}

類不符合要求,因?yàn)樗且粋€(gè)引用類型,因此可以從其他并發(fā)域變異。換句話說,該類文章(Article)的傳遞不是線程安全的,所以編譯器不能隱式地將其標(biāo)記為遵守Sendable協(xié)議。

使用泛型和枚舉時(shí)的隱式一致性

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

// 因?yàn)?Value 沒有遵守 Sendable 協(xié)議,所以 Container 也不會(huì)自動(dòng)的隱式遵守該協(xié)議
struct Container<Value> {
    var child: Value
}

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

// Container 隱式地符合 Sendable,因?yàn)樗乃泄矊傩砸彩侨绱恕?
struct Container<Value: Sendable> {
    var child: Value
}

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

你可以看到,我們自動(dòng)從編譯器中得到一個(gè)錯(cuò)誤:

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

我們可以通過使用一個(gè)值類型String來解決這個(gè)錯(cuò)誤,因?yàn)樗呀?jīng)符合Sendable。

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

從線程安全的實(shí)例中拋出錯(cuò)誤

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

struct ArticleSavingError: Error {
    var author: NonFinalAuthor
}
extension ArticleSavingError: Sendable { }

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

Stored property ‘author’ of ‘Sendable’-conforming struct ‘ArticleSavingError’ has non-sendable type ‘NonFinalAuthor’

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

如何使用Sendable協(xié)議

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

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

/// User 是不可改變的,因此是線程安全的,所以可以遵守 Sendable 協(xié)議
final class User: Sendable {
    let name: String
    init(name: String) { self.name = name }
}

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

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的限制

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

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

public struct Article {
    internal var title: String
}

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

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

由于該類是非最終的,我們無法符合Sendable協(xié)議的要求,因?yàn)槲覀儾淮_定其他類是否會(huì)繼承User的非Sendable成員。因此,我們會(huì)遇到以下錯(cuò)誤:

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

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

class User: @unchecked Sendable {
    let name: String
    init(name: String) { self.name = name }
}

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

如何使用 @Sendabele

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

SE-302的部分動(dòng)機(jī)是執(zhí)行盡可能少的同步

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

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

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

如果你用非 Sendabel 類型的閉包,我們會(huì)遇到一個(gè)錯(cuò)誤:

let listOfArticles = ArticlesList()
var searchKeyword: NSAttributedString? = NSAttributedString(string: "keyword")
let filteredArticles = await listOfArticles.filteredArticles { article in
    // Error: Reference to captured var 'searchKeyword' in concurrently-executing code
    guard let searchKeyword = searchKeyword else { return false }
    return article.title == searchKeyword.string
}

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

Swift 6: 為你的代碼啟用嚴(yán)格的并發(fā)性檢查

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

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

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

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

Enabling strict concurrency in Xcode 14

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

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

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

@preconcurrency import SharedWithYou

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

以上就是Swift 并發(fā)修改Sendable 閉包實(shí)例詳解的詳細(xì)內(nèi)容,更多關(guān)于Swift 并發(fā)修改Sendable 閉包的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • switch實(shí)現(xiàn)一個(gè)兩數(shù)的運(yùn)算代碼示例

    switch實(shí)現(xiàn)一個(gè)兩數(shù)的運(yùn)算代碼示例

    這篇文章主要介紹了switch實(shí)現(xiàn)一個(gè)兩數(shù)的運(yùn)算代碼示例,需要的朋友可以參考下
    2017-06-06
  • 簡單了解Swift語言中的break和continue語句的用法

    簡單了解Swift語言中的break和continue語句的用法

    這篇文章主要簡單介紹了Swift語言中的break和continue語句的用法,與其他語言的一樣用于循環(huán)語句流程控制,需要的朋友可以參考下
    2015-11-11
  • swift內(nèi)存管理指針類型使用實(shí)例詳解

    swift內(nèi)存管理指針類型使用實(shí)例詳解

    這篇文章主要為大家介紹了swift內(nèi)存管理指針類型使用實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Swift?Sequence?Collection使用示例學(xué)習(xí)

    Swift?Sequence?Collection使用示例學(xué)習(xí)

    這篇文章主要為大家介紹了Swift?Sequence?Collection使用示例學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Swift教程之函數(shù)詳解

    Swift教程之函數(shù)詳解

    這篇文章主要介紹了Swift教程之函數(shù)詳解,本文講解了函數(shù)的聲明與調(diào)用、函數(shù)的參數(shù)和返回值、函數(shù)參數(shù)名、函數(shù)類型等內(nèi)容,需要的朋友可以參考下
    2015-01-01
  • Swift data范圍截取問題解決方案

    Swift data范圍截取問題解決方案

    這篇文章主要介紹了Swift data范圍截取問題解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • Swift 圖表使用Foudation庫中測量類型詳解

    Swift 圖表使用Foudation庫中測量類型詳解

    這篇文章主要為大家介紹了Swift 圖表使用Foudation庫中測量類型詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Swift方法調(diào)度之類的普通方法底層探究

    Swift方法調(diào)度之類的普通方法底層探究

    這篇文章主要介紹了Swift-方法調(diào)度-類的普通方法底層探究,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • switch多選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu)示例詳解

    switch多選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu)示例詳解

    這篇文章主要介紹了switch多選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu),本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • Swift讀取App的版本信息與PCH文件詳解

    Swift讀取App的版本信息與PCH文件詳解

    這篇文章主要介紹了Swift讀取App的版本信息與PCH文件的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-03-03

最新評(píng)論

吉木乃县| 达孜县| 高唐县| 洛南县| 河西区| 大荔县| 沈阳市| 江门市| 石泉县| 大埔区| 南江县| 于田县| 无锡市| 旌德县| 四会市| 称多县| 紫云| 五原县| 高碑店市| 德清县| 乌拉特前旗| 湖南省| 本溪市| 巫山县| 郯城县| 广西| 贡山| 申扎县| 瓦房店市| 安多县| 青浦区| 广饶县| 来安县| 衡水市| 毕节市| 三都| 镇雄县| 枣庄市| 三亚市| 武安市| 广州市|