前言:
Swift 是一个类型安全(type safe)的语言,编码的过程中类型都是确定的,所以Swift 并不推荐大家直接使用指针。
但是某一些场景下,使用指针是非常便捷的。比如链表中的多个结点的Value是相同的,如果想要对结点标识唯一,可以通过结点的next 指针获取到对应的内存地址,把内存地址当做唯一标识。
Swift 指针操作
获取一个结构体对应的内存地址:
let struct = xxx
var memoryPointer: Int64 = 0
withUnsafePointer(to: & struct) { ptr in
memoryPointer = unsafeBitCast(ptr.pointee, to: Int64.self)
}
相关知识点
Swift 对于指针相关的操作提供了多种结构体方便使用,常见的比如UnsafePointer
和 UnsafeMutablePointer
,他们的区分可以简单的理解为可变与不可变。
详细的使用以UnsafePointer
举例:
我们可以使用UnsafePointer
类型的实例来访问一个内存中的特定类型,这个特定的类型就是指针的 Pointee
类型。同时,Swift也支持暂时或永久的转换UnsafePointer
中的Pointee
类型。
- 临时访问一个指针的内存作为一个不同的类型:
let uint8Pointer: UnsafePointer<UInt8> = fetchEightBytes()
let length = uint8Pointer.withMemoryRebound(to: Int8.self, capacity: 8)
- 永久的重新绑定到不同类型,首先获取指向内存的原始指针,然后调用原指针的
bindMemory(to:capacity:)
方法。
/// 注意:将`uint8Pointer`引用的内存重新绑定到`UInt64`后,
/// 作为`UInt8`实例访问该指针的引用内存是不明确的。
/// var fullInteger = uint64Pointer.pointee // OK
/// var firstByte = uint8Pointer.pointee // undefined
uint64Pointer = UnsafeRawPointer(uint8Pointer).bindMemory(to: UInt64.self, capacity: 1)
此外,还有一种方法能够读取不同的指针类型。首先把指针转为UnsafeRawPointer
,然后通过load
方法得到不同的类型:
let rawPointer = UnsafeRawPointer(uint64Pointer)
let fullInteger = rawPointer.load(as: UInt64.self)
let firstByte = rawPointer.load(as: UInt8.self)