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

Swift在什么情況會(huì)發(fā)生內(nèi)存訪問(wèn)沖突詳解

 更新時(shí)間:2021年01月12日 16:11:12   作者:_GodIsCoder  
這篇文章主要給大家介紹了關(guān)于Swift在什么情況會(huì)發(fā)生內(nèi)存訪問(wèn)沖突的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

眾所周知,Swift 是一門(mén)類(lèi)型安全的語(yǔ)言,它會(huì)通過(guò)編譯器報(bào)錯(cuò)來(lái)阻止你代碼中不安全的行為。比如變量必須在使用之前聲明、變量被銷(xiāo)毀之后內(nèi)存不能在訪問(wèn)、數(shù)組越界等問(wèn)題。

Swift 會(huì)通過(guò)對(duì)于修改同一塊內(nèi)存,同一時(shí)間以互斥訪問(wèn)權(quán)限的方式(同一時(shí)間,只能有一個(gè)寫(xiě)權(quán)限),來(lái)確保你的代碼不會(huì)發(fā)生內(nèi)存訪問(wèn)沖突。雖然 Swift 是自動(dòng)管理內(nèi)存的,在大多數(shù)情況下你并不需要關(guān)心這個(gè)。但理解何種情況下會(huì)發(fā)生內(nèi)存訪問(wèn)沖突也是十分必要的。

首先,來(lái)看一下什么是內(nèi)存訪問(wèn)沖突。

內(nèi)存訪問(wèn)沖突

當(dāng)你設(shè)值或者讀取變量的值得時(shí)候,就會(huì)訪問(wèn)內(nèi)存。

var age = 10 // 寫(xiě)權(quán)限
print(age) // 讀權(quán)限

當(dāng)我們對(duì)同一塊內(nèi)存,同時(shí)進(jìn)行讀寫(xiě)操作時(shí),會(huì)產(chǎn)生不可預(yù)知的錯(cuò)誤。比如上面的 age,假如在你讀取它值的期間有別的代碼將它設(shè)為 20,那么你讀取到的有可能是 10,也有可能是 20。這就產(chǎn)生了問(wèn)題。

內(nèi)存訪問(wèn)沖突:對(duì)同一塊內(nèi)存,同時(shí)進(jìn)行讀寫(xiě)操作,或者同時(shí)進(jìn)行多個(gè)寫(xiě)入操作時(shí),就會(huì)造成內(nèi)存訪問(wèn)沖突。

了解了什么是內(nèi)存訪問(wèn)沖突,下面來(lái)看下什么情況下回造成內(nèi)存訪問(wèn)沖突。

In-Out 參數(shù)

當(dāng) In-Out 參數(shù)為全局變量,并且該變量在函數(shù)體內(nèi)被修改時(shí),就會(huì)造成內(nèi)存訪問(wèn)沖突。比如下面的代碼:

var age = 10

func increment(_ num: inout Int) { // step1
 num += age // step2
}
increment(&age)

increment(:) 在整個(gè)函數(shù)體內(nèi),對(duì)所有的 In-Out 參數(shù)都有寫(xiě)權(quán)限。在上述代碼中,step1 已經(jīng)獲得了 age 的寫(xiě)權(quán)限,而 step2 有得到了 age 的讀權(quán)限,這樣就造成了同一塊內(nèi)存,同時(shí)進(jìn)行了讀寫(xiě)操作。從而造成了內(nèi)存訪問(wèn)沖突。

上面的問(wèn)題可以通過(guò)將 age 拷貝一份來(lái)解決:

// step1
var copyOfAge = age
increment(&copyOfAge)
age = copyOfAge

step1 將 age 的值拷貝到另一塊內(nèi)存上,這樣在函數(shù)體內(nèi)就是存在對(duì) age 的讀權(quán)限和對(duì) copyOfAge 的寫(xiě)權(quán)限,因?yàn)?age 和 copyOfAge 是兩塊內(nèi)存,所以就不會(huì)造成內(nèi)存訪問(wèn)沖突。

結(jié)構(gòu)體的 mutating 函數(shù)

對(duì)于結(jié)構(gòu)體的 mutating 函數(shù)來(lái)說(shuō),它整個(gè)函數(shù)體都有 self 的寫(xiě)權(quán)限。

struct Person {
 var age: Int
 mutating func increment(_ num: inout Int) { 
  age += num 
 }
}

var p1 = Person(age: 10)
p1.increment(&p1.age)

上述的代碼編譯器會(huì)報(bào)錯(cuò):Overlapping accesses to 'p1', but modification requires exclusive access; consider copying to a local variable。很明顯這是一個(gè)內(nèi)存訪問(wèn)沖突。

In-Out 參數(shù)獲得了 p1 的寫(xiě)權(quán)限;mutating 函數(shù)也獲得了 p1 的寫(xiě)權(quán)限。同一塊內(nèi)存,同時(shí)有兩個(gè)寫(xiě)操作。造成內(nèi)存訪問(wèn)沖突??梢酝ㄟ^(guò)同上的拷貝操作來(lái)解決。

值類(lèi)型的屬性

對(duì)于結(jié)構(gòu)體、枚舉、元祖等值類(lèi)型來(lái)說(shuō),修改它們的屬性就相當(dāng)于修改它們整個(gè)的值。比如下面的代碼:

func increment(_ num1: inout Int, _ num2: inout Int) {
 print(num1 + num2)
}

var tuple = (age: 10, height: 20)
increment(&tuple.age, &tuple.height)

&tuple.age 拿到了 tuple 的寫(xiě)權(quán)限,&tuple.height 又拿了 tuple 的寫(xiě)權(quán)限。同一塊內(nèi)存,同時(shí)有兩個(gè)寫(xiě)操作。造成內(nèi)存訪問(wèn)沖突。

這個(gè)問(wèn)題可以通過(guò)局部變量來(lái)解決:

func someFunction() {
 var tuple = (age: 10, height: 20)
 increment(&tuple.age, &tuple.height)
}

因?yàn)樵?someFunction() 函數(shù)里,age 和 height 沒(méi)有產(chǎn)生任何的交互(沒(méi)有在其期間去讀取或者寫(xiě)入 age 和 height),所以編譯器可以保證內(nèi)存安全。

PS:關(guān)于評(píng)論區(qū)的問(wèn)題,在 someFunction() 函數(shù)里沒(méi)有任何交互是什么意思?

答:在someFunction() 里,編譯器可以保證沒(méi)有別的線程來(lái)讀取或者修改 tuple。因此,可以保證內(nèi)存安全。而對(duì)于全局變量,編譯器無(wú)法保證是否有別的線程在讀取或者修改。

下面的代碼就是在函數(shù)體內(nèi)有交互的代碼,雖然是局部變量,但涉及多個(gè)線程修改 tuple 的值,因此會(huì)造成內(nèi)存訪問(wèn)沖突:

func someFunction() {
 var tuple = (age: 10, height: 20)
 
 DispatchQueue.main.async {
  tuple.age += 10
 }
 
 DispatchQueue.main.async {
  increment(&tuple.age, &tuple.height)
 }
}

總結(jié)

對(duì)同一塊內(nèi)存,同時(shí)進(jìn)行讀寫(xiě)操作,或者同時(shí)進(jìn)行多個(gè)寫(xiě)入操作時(shí),就會(huì)造成內(nèi)存訪問(wèn)沖突。

會(huì)造成內(nèi)存訪問(wèn)沖突的情況:

  • In-Out 為全局參數(shù),并且在函數(shù)體內(nèi)修改了它。
  • 結(jié)構(gòu)體的 mutating 函數(shù)內(nèi)修改結(jié)構(gòu)體的值。
  • 同一值類(lèi)型的多個(gè)屬性當(dāng)做函數(shù)的 In-Out 參數(shù)。

到此這篇關(guān)于Swift在什么情況會(huì)發(fā)生內(nèi)存訪問(wèn)沖突的文章就介紹到這了,更多相關(guān)Swift內(nèi)存訪問(wèn)沖突內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • iOS Swift UICollectionView橫向分頁(yè)滾動(dòng),cell左右排版問(wèn)題詳解

    iOS Swift UICollectionView橫向分頁(yè)滾動(dòng),cell左右排版問(wèn)題詳解

    UICollectionView是iOS中比較常見(jiàn)的一個(gè)控件,這篇文章主要給大家介紹了關(guān)于iOS Swift UICollectionView橫向分頁(yè)滾動(dòng),cell左右排版問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • swift中的@UIApplicationMain示例詳解

    swift中的@UIApplicationMain示例詳解

    這篇文章主要給大家介紹了關(guān)于swift中@UIApplicationMain的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • swift中正確安全聲明一個(gè)單例的方法實(shí)例

    swift中正確安全聲明一個(gè)單例的方法實(shí)例

    這篇文章主要給大家介紹了關(guān)于swift中如何正確安全聲明一個(gè)單例的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 關(guān)于Swift 4.1中的Codable改進(jìn)詳解

    關(guān)于Swift 4.1中的Codable改進(jìn)詳解

    這篇文章主要給大家介紹了關(guān)于Swift 4.1中的Codable改進(jìn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-02-02
  • 深入解析Swift代理模式

    深入解析Swift代理模式

    委托(代理)是一種設(shè)計(jì)模式,它允許類(lèi)或結(jié)構(gòu)體將一些需要它們負(fù)責(zé)的功能交由(委托)給其他的類(lèi)型。下面這篇文章主要介紹了Swift代理模式的相關(guān)資料,文章開(kāi)始先介紹了Objective-C相關(guān)的內(nèi)容,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-03-03
  • 窺探Swift編程中的錯(cuò)誤處理與異常拋出

    窺探Swift編程中的錯(cuò)誤處理與異常拋出

    本文給大家整理些關(guān)于Swift編程中的錯(cuò)誤處理與異常拋出,本文介紹的非常詳細(xì),基于參考價(jià)值,特此分享腳本之家平臺(tái)供大家學(xué)習(xí)
    2016-02-02
  • Swift用final關(guān)鍵字來(lái)防止重寫(xiě)

    Swift用final關(guān)鍵字來(lái)防止重寫(xiě)

    final關(guān)鍵字在大多數(shù)的編程語(yǔ)言中都存在,表示不允許對(duì)其修飾的內(nèi)容進(jìn)行繼承或者重新操作。下面通過(guò)實(shí)例代碼給大家介紹swift用final關(guān)鍵字來(lái)防止重寫(xiě)
    2016-12-12
  • Swift語(yǔ)言中字符串相關(guān)的基本概念解析

    Swift語(yǔ)言中字符串相關(guān)的基本概念解析

    這篇文章主要介紹了Swift語(yǔ)言中字符串相關(guān)的基本概念解析,是Swift入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-11-11
  • Swift如何調(diào)用Objective-C的可變參數(shù)函數(shù)詳解

    Swift如何調(diào)用Objective-C的可變參數(shù)函數(shù)詳解

    這篇文章主要給大家介紹了關(guān)于Swift如何調(diào)用Objective-C的可變參數(shù)函數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用swift具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • Objective-C和Swift的轉(zhuǎn)換速查手冊(cè)(推薦)

    Objective-C和Swift的轉(zhuǎn)換速查手冊(cè)(推薦)

    這篇文章主要給大家介紹了關(guān)于Objective-C和Swift的轉(zhuǎn)換速查手冊(cè)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),非常推薦給大家參考學(xué)習(xí)使用,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)不
    2018-06-06

最新評(píng)論

黄冈市| 华坪县| 读书| 灵宝市| 永顺县| 西平县| 云林县| 乌鲁木齐市| 马关县| 民和| 万州区| 平乡县| 潮安县| 新疆| 高青县| 伊宁县| 海宁市| 汕头市| 东阿县| 苍山县| 荥阳市| 中卫市| 玛纳斯县| 将乐县| 郎溪县| 永定县| 西华县| 白山市| 侯马市| 平谷区| 黑水县| 邓州市| 新田县| 吉安县| 台南市| 莱阳市| 定西市| 尚义县| 长兴县| 遂川县| 黎城县|