前言:
Swift 是一個類型安全(type safe)的語言,編碼的過程中類型都是確定的,所以Swift 并不推薦大家直接使用指針。
但是某一些場景下,使用指針是非常便捷的。比如鏈表中的多個結(jié)點(diǎn)的Value是相同的,如果想要對結(jié)點(diǎn)標(biāo)識唯一,可以通過結(jié)點(diǎn)的next 指針獲取到對應(yīng)的內(nèi)存地址,把內(nèi)存地址當(dāng)做唯一標(biāo)識。
Swift 指針操作
獲取一個結(jié)構(gòu)體對應(yīng)的內(nèi)存地址:
let struct = xxx
var memoryPointer: Int64 = 0
withUnsafePointer(to: & struct) { ptr in
memoryPointer = unsafeBitCast(ptr.pointee, to: Int64.self)
}
相關(guān)知識點(diǎn)
Swift 對于指針相關(guān)的操作提供了多種結(jié)構(gòu)體方便使用,常見的比如UnsafePointer 和 UnsafeMutablePointer,他們的區(qū)分可以簡單的理解為可變與不可變。
詳細(xì)的使用以UnsafePointer 舉例:
我們可以使用UnsafePointer 類型的實(shí)例來訪問一個內(nèi)存中的特定類型,這個特定的類型就是指針的 Pointee類型。同時,Swift也支持暫時或永久的轉(zhuǎn)換UnsafePointer 中的Pointee類型。
- 臨時訪問一個指針的內(nèi)存作為一個不同的類型:
let uint8Pointer: UnsafePointer<UInt8> = fetchEightBytes()
let length = uint8Pointer.withMemoryRebound(to: Int8.self, capacity: 8)
- 永久的重新綁定到不同類型,首先獲取指向內(nèi)存的原始指針,然后調(diào)用原指針的
bindMemory(to:capacity:)方法。
/// 注意:將`uint8Pointer`引用的內(nèi)存重新綁定到`UInt64`后,
/// 作為`UInt8`實(shí)例訪問該指針的引用內(nèi)存是不明確的。
/// var fullInteger = uint64Pointer.pointee // OK
/// var firstByte = uint8Pointer.pointee // undefined
uint64Pointer = UnsafeRawPointer(uint8Pointer).bindMemory(to: UInt64.self, capacity: 1)
此外,還有一種方法能夠讀取不同的指針類型。首先把指針轉(zhuǎn)為UnsafeRawPointer,然后通過load方法得到不同的類型:
let rawPointer = UnsafeRawPointer(uint64Pointer)
let fullInteger = rawPointer.load(as: UInt64.self)
let firstByte = rawPointer.load(as: UInt8.self)