日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

swift指針及內存管理內存綁定實例詳解_Swift

作者:i_erlich ? 更新時間: 2022-12-23 編程語言

swift API 綁定

swift提供了3種不同的API來綁定/重新綁定指針

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

繞過編譯器檢查 - assumingMemoryBound

就是假定內存綁定

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))
}

其實 兩者本質沒什么區別,都是指向內存的指針

UnsafePointer 指向1塊Int內存

UnsafePointer<Int, Int> 指向一個元組tuple內存, 也就是一塊連續的內存,包含連個連續的Int

兩者都是首地址

一種方式就是不 強轉 UnsafePointer<Int, Int> 為 UnsafePointer

  • 先把 元組指針轉換成原始指針 UnsafeRawPointer(tuplePtr)
  • 原始指針調用 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))
}

結果

30

40

assumingMemoryBound的意義在于:

有時候不想做指針類型轉換來增加代碼的復雜度

就可以調用 此api繞過編譯器檢查,但是并沒有發生實際的指針轉換

內存轉換 - bindMemory

實際發生了轉換,改變當前內存指針綁定的類型

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))
}

結果

30

40

bindMemory - 相比于assumingMemoryBound,就是改變內存綁定類型

臨時改變內存綁定 - 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)
})

結果

0x000000000000001e

withMemoryRebound意義在于:

臨時改變內存綁定,出了api 尾隨閉包作用域之后,綁定就不存在了

最后,補充一個小tip

也許你會對swift 閉包 函數的語法形式感覺會不習慣,編譯器也會自動直接轉變為函數體

其實高級語言語法習慣僅僅就是一種語法而已

底層其實是函數棧的形式

一個函數 包括 函數名(也就是方法指針),多個參數,函數體(包含多個變量與調用)

內存表達函數的方式就是棧的形式:

入棧順序: 函數指針,參數順序入棧,函數體內部逐行順序入棧

按照這個邏輯,最后一個尾隨閉包參數就可以直接變為函數體,這樣并不影響函數棧的入棧方式

原文鏈接:https://juejin.cn/post/7168942846194483207

欄目分類
最近更新