欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

SwiftArraycopy的線程安全問題

    

創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務,包含不限于成都網(wǎng)站制作、網(wǎng)站設計、外貿網(wǎng)站建設、東港網(wǎng)絡推廣、小程序開發(fā)、東港網(wǎng)絡營銷、東港企業(yè)策劃、東港品牌公關、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務,您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)建站為所有大學生創(chuàng)業(yè)者提供東港建站搭建服務,24小時服務熱線:13518219792,官方網(wǎng)址:www.aaarwkj.com

Swift Array copy 的線程安全問題

NSArray 繼承自 NSObject,屬于對象,有 copy 方法。Swift 的 Array 是 struct,沒有 copy 方法。把一個 Array 變量賦值給另一個變量,兩個變量的內存地址相同嗎?與此相關的有多線程安全問題。本文探究這兩個問題。

內存地址

定義測試 class 和 struct

class MyClass {    
    var intArr = [Int]()    var structArr = [MyStructElement]()    var objectArr = [MyClassElement]()
}struct MyStructElement {}class MyClassElement {}

定義輸出內存地址的 closure

let memoryAddress: (Any) -> String = {    guard let cVarArg = $0 as? CVarArg else { return "Can not find memory address" }    return String(format: "%p", cVarArg)
}

測試 Int array

private func testIntArr() {    print(#function)    
    let my = MyClass()    for i in 0...10000 {
        my.intArr.append(i)
    }    print("Before arr address:", memoryAddress(my.intArr))        
    // Copy Array is NOT thread safe
    let arr = my.intArr // If move this into async closure, crash
    print("Temp   arr address:", memoryAddress(arr)) // Copy. Address different from my.intArr
    DispatchQueue.global().async {        var sum = 0
        for i in arr {
            sum += i
        }        print("Sum:", sum) // 0 + 1 + ... + 10000 = 50005000
    }
    
    my.intArr.removeAll()    for _ in 0...10000 {
        my.intArr.append(0)
    }    print("After  arr address:", memoryAddress(my.intArr)) // New address}

在 view controller 中進行測試

override func viewDidLoad() {    super.viewDidLoad()    
    for _ in 0...1000 {
        testIntArr()
    }
}

結果

Int array 的內存地址不同,賦值過程發(fā)生了 copy。

測試 struct array

private func testStructArr() {    print(#function)    
    let my = MyClass()    for _ in 0...10000 {
        my.structArr.append(MyStructElement())
    }    print("Before arr address:", memoryAddress(my.structArr))    
    // Copy Array is NOT thread safe
    let arr = my.structArr // If move this into async closure, crash
    print("Temp   arr address:", memoryAddress(arr)) // Copy. Address different from my.structArr
    DispatchQueue.global().async {        var sum = 0
        for _ in arr {
            sum += 1
        }        print("Sum:", sum) // 10001
    }
        
    my.structArr.removeAll()    for _ in 0...10000 {
        my.structArr.append(MyStructElement())
    }    print("After  arr address:", memoryAddress(my.structArr)) // New address}

在 view controller 中進行測試

override func viewDidLoad() {    super.viewDidLoad()    
    for _ in 0...1000 {
        testStructArr()
    }
}

結果

Struct array 的內存地址不同,賦值過程發(fā)生了 copy。

測試 Object array

private func testObjectArr() {    print(#function)    
    let my = MyClass()    for _ in 0...10000 {
        my.objectArr.append(MyClassElement())
    }    print("Before arr address:", memoryAddress(my.objectArr))    
    // Copy Array is NOT thread safe
    let arr = my.objectArr // If move this into async closure, crash
    print("Temp   arr address:", memoryAddress(arr)) // Not copy. Same as my.objectArr
    DispatchQueue.global().async {        var sum = 0
        for _ in arr {
            sum += 1
        }        print("Sum:", sum) // 10001
    }
        
    my.objectArr.removeAll()    for _ in 0...10000 {
        my.objectArr.append(MyClassElement())
    }    print("After  arr address:", memoryAddress(my.objectArr)) // New address}

在 view controller 中進行測試

override func viewDidLoad() {    super.viewDidLoad()    
    for _ in 0...1000 {
        testObjectArr()
    }
}

結果

一個 object array 變量賦值給另一個變量,兩個變量的內存地址相同,也就是說沒有 copy。原來的 array 改變后,內存地址改變,但不影響被賦值的變量。

線程安全問題

以上的寫法是不會報錯的。如果把 array 的賦值寫入 async closure,就會報錯。多試幾次,會有不同的錯誤。

Int array 的錯誤

DispatchQueue.global().async {    let arr = my.intArr // 在這里賦值會報錯
    var sum = 0
    for i in arr {
        sum += i
    }    print("Sum:", sum)
}

Struct array 的錯誤

DispatchQueue.global().async {    let arr = my.structArr // 在這里賦值會報錯
    var sum = 0
    for _ in arr {
        sum += 1
    }    print("Sum:", sum)
}

Object array 的錯誤

DispatchQueue.global().async {    let arr = my.objectArr // 在這里賦值會報錯
    var sum = 0
    for _ in arr {
        sum += 1
    }    print("Sum:", sum)
}

對于 Int array 和 struct array 來說,賦值時進行了 copy,但這個步驟應該不是原子操作,所以放入 async closure 會出錯。對于 object array 來說,賦值過程雖然沒有進行 copy,但是要改變原來的 array 并且保持被賦值的對象不變,應該也要進行 copy;也就是說在更新 array 時才進行 copy。推測此時的 copy 也不是原子操作,所以放入 async closure 會出錯。

Array 的賦值過程是否進行 copy,與其中的元素類型有關。如果 array 的元素是 Int、struct 等,在賦值時就 copy。如果 array 的元素是 object,在賦值時不 copy,賦值后在更新其中一個 array 變量時才 copy。Array 的 copy 是線程不安全的。

文章名稱:SwiftArraycopy的線程安全問題
本文地址:http://www.aaarwkj.com/article6/isjjig.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供外貿建站、用戶體驗網(wǎng)站建設、品牌網(wǎng)站設計、域名注冊、定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

h5響應式網(wǎng)站建設
亚洲欧美一区二区三区日本| 中文字幕日韩欧美一区| av成熟一区二区三区| 欧美日韩在线不卡一区| 国产一区二区三区自拍| 国产女主播精品视频一区| 欧美日本道一区二区三区| 国产精品一区二区综合亚洲| 亚洲国产理论片在线观看| 日本一区二区久久人妻高清| 91午夜精品在线观看| 国内传媒视频免费观看| 久久国产精品一区av瑜伽| 人人看男人的天堂东京| 亚洲国产av永久精品成人| 亚洲国产一区二区精品| 成人精品播放视频在线观看| 精华国产一区二区三区| 亚洲国产欧美日韩在线不卡成人| 国产精品久久久久精品日日三级 | 亚洲国产成人不卡高清麻豆| 国产精品午夜福利天堂| 国产一区av剧情巨作| 亚洲中文字幕乱码丝袜在线精品 | 日本电影在线看一区二区| 亚洲av成人在线资源| 精品国产91久久粉嫩| 亚洲一区二区三区色偷偷| 久久国产亚洲精品赲碰热| 欧美偷拍一区二区三区| 五月婷婷丁香在线观看| 人人妻人人澡人人爽的视频 | 日韩欧美国产麻豆91在线精品| 欧美αv一区二区三区| 欧美日韩一区二区三区色| 亚洲青青草原一区二区| 中文字幕人妻中文av不卡专区| 精品人妻一区二区三区免费视频| 日本伦理三级在线观看| 亚洲国产精品久久久久国产精品| 丝袜美腿亚洲欧美日韩|