swift指針&內(nèi)存管理-內(nèi)存綁定

swift提供了3種不同的API來(lái)綁定/重新綁定指針

  • assumingMemoryBound(to:)
  • bindMemory(to: capacity:)
  • withMemoryRebound(to: capacity: body:)

繞過編譯器檢查 - assumingMemoryBound

就是假定內(nèi)存綁定

func testPointer(_ p: UnsafePointer<Int>) {
    print(p)
}
let tuple = (30, 40)
withUnsafePointer(to: tuple) { (tuplePtr: UnsafePointer<(Int, Int)>) in
    testPointer(UnsafeRawPointer(tuplePtr)
    .assumingMemoryBound(to: Int.self))
}
image.png

其實(shí) 兩者本質(zhì)沒什么區(qū)別,都是指向內(nèi)存的指針

UnsafePointer<Int> 指向1塊Int內(nèi)存

UnsafePointer<Int, Int> 指向一個(gè)元組tuple內(nèi)存, 也就是一塊連續(xù)的內(nèi)存,包含連個(gè)連續(xù)的Int

兩者都是首地址

一種方式就是不 強(qiáng)轉(zhuǎn) UnsafePointer<Int, Int> 為 UnsafePointer<Int>

  1. 先把 元組指針轉(zhuǎn)換成原始指針 UnsafeRawPointer(tuplePtr)
  2. 原始指針調(diào)用 assumingMemoryBound 綁定成Int 指針 UnsafeRawPointer(tuplePtr).assumingMemoryBound(to: Int.self)
func testPointer(_ p: UnsafePointer<Int>) {
    print(p[0])
    print(p[1])
}
let tuple = (30, 40)
withUnsafePointer(to: tuple) { (tuplePtr: UnsafePointer<(Int, Int)>) in
    testPointer(UnsafeRawPointer(tuplePtr).assumingMemoryBound(to: Int.self))
}

結(jié)果

30

40

assumingMemoryBound的意義在于:

有時(shí)候不想做指針類型轉(zhuǎn)換來(lái)增加代碼的復(fù)雜度

就可以調(diào)用 此api繞過編譯器檢查,但是并沒有發(fā)生實(shí)際的指針轉(zhuǎn)換

內(nèi)存轉(zhuǎn)換 - bindMemory

實(shí)際發(fā)生了轉(zhuǎn)換,改變當(dāng)前內(nèi)存指針綁定的類型

func testPointer(_ p: UnsafePointer<Int>) {
    print(p[0])
    print(p[1])
}
let tuple = (30, 40)
withUnsafePointer(to: tuple) { (tuplePtr: UnsafePointer<(Int, Int)>) in
    testPointer(UnsafeRawPointer(tuplePtr)
    .bindMemory(to: Int.self, capacity: 1))
}

結(jié)果

30

40

bindMemory - 相比于assumingMemoryBound,就是改變內(nèi)存綁定類型

臨時(shí)改變內(nèi)存綁定 - withMemoryRebound

func testPointer(_ p: UnsafePointer<Int8>) {
    print(p)
}

let UInt8Ptr = UnsafePointer<UInt8>.init(bitPattern: 30)
UInt8Ptr?.withMemoryRebound(to: Int8.self, capacity: 1, 
    { (Int8Ptr: UnsafePointer<Int8>) in
    testPointer(Int8Ptr)
})

結(jié)果

0x000000000000001e

withMemoryRebound意義在于:

臨時(shí)改變內(nèi)存綁定,出了api 尾隨閉包作用域之后,綁定就不存在了

最后,補(bǔ)充一個(gè)小tip

也許你會(huì)對(duì)swift 閉包 函數(shù)的語(yǔ)法形式感覺會(huì)不習(xí)慣,編譯器也會(huì)自動(dòng)直接轉(zhuǎn)變?yōu)楹瘮?shù)體

其實(shí)高級(jí)語(yǔ)言語(yǔ)法習(xí)慣僅僅就是一種語(yǔ)法而已

底層其實(shí)是函數(shù)棧的形式

一個(gè)函數(shù) 包括 函數(shù)名(也就是方法指針),多個(gè)參數(shù),函數(shù)體(包含多個(gè)變量與調(diào)用)

內(nèi)存表達(dá)函數(shù)的方式就是棧的形式:

入棧順序: 函數(shù)指針,參數(shù)順序入棧,函數(shù)體內(nèi)部逐行順序入棧

按照這個(gè)邏輯,最后一個(gè)尾隨閉包參數(shù)就可以直接變?yōu)楹瘮?shù)體,這樣并不影響函數(shù)棧的入棧方式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 指針 Swift中指針分為兩類: typed pointer:指定數(shù)據(jù)類型指針,UnsafePointer<T>,...
    YY323閱讀 3,032評(píng)論 0 1
  • swift 進(jìn)階之路:學(xué)習(xí)大綱[http://www.itdecent.cn/p/115367c3eefd] 前...
    歐德爾丶胡閱讀 767評(píng)論 1 2
  • 指針 為什么說指針不安全 比如我們?cè)趧?chuàng)建一個(gè)對(duì)象的時(shí)候,是需要在堆分配內(nèi)存空間的。但是這個(gè)內(nèi)存空間的聲明周期是有限...
    晨曦的簡(jiǎn)書閱讀 573評(píng)論 0 1
  • 背景 大部分情況下做Swift開發(fā)是不需要使用指針的,也不建議使用,但是有時(shí)候?qū)懕容^底層的東西就需要了。最近一段時(shí)...
    小涼介閱讀 2,371評(píng)論 1 7
  • 5.函數(shù) 1.基本定義 func 函數(shù)名(參數(shù)) -> 返回值 { } 2.相關(guān)注意點(diǎn) 1.參數(shù)默認(rèn)let,不是v...
    我是一只攻城獅_ifYou閱讀 631評(píng)論 0 1

友情鏈接更多精彩內(nèi)容