swift提供了3種不同的API來綁定/重新綁定指針
- 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))
}
其實 兩者本質(zhì)沒什么區(qū)別,都是指向內(nèi)存的指針
UnsafePointer<Int> 指向1塊Int內(nèi)存
UnsafePointer<Int, Int> 指向一個元組tuple內(nèi)存, 也就是一塊連續(xù)的內(nèi)存,包含連個連續(xù)的Int
兩者都是首地址
一種方式就是不 強(qiáng)轉(zhuǎn) UnsafePointer<Int, Int> 為 UnsafePointer<Int>
- 先把 元組指針轉(zhuǎn)換成原始指針 UnsafeRawPointer(tuplePtr)
- 原始指針調(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的意義在于:
有時候不想做指針類型轉(zhuǎn)換來增加代碼的復(fù)雜度
就可以調(diào)用 此api繞過編譯器檢查,但是并沒有發(fā)生實際的指針轉(zhuǎn)換
內(nèi)存轉(zhuǎn)換 - bindMemory
實際發(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)存綁定類型
臨時改變內(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意義在于:
臨時改變內(nèi)存綁定,出了api 尾隨閉包作用域之后,綁定就不存在了
最后,補(bǔ)充一個小tip
也許你會對swift 閉包 函數(shù)的語法形式感覺會不習(xí)慣,編譯器也會自動直接轉(zhuǎn)變?yōu)楹瘮?shù)體
其實高級語言語法習(xí)慣僅僅就是一種語法而已
底層其實是函數(shù)棧的形式
一個函數(shù) 包括 函數(shù)名(也就是方法指針),多個參數(shù),函數(shù)體(包含多個變量與調(diào)用)
內(nèi)存表達(dá)函數(shù)的方式就是棧的形式:
入棧順序: 函數(shù)指針,參數(shù)順序入棧,函數(shù)體內(nèi)部逐行順序入棧
按照這個邏輯,最后一個尾隨閉包參數(shù)就可以直接變?yōu)楹瘮?shù)體,這樣并不影響函數(shù)棧的入棧方式