Swift 指针 & 内存管理
目录
一、指针
Swift 指针的不安全性:
- 可以指向已经释放的内存区域(内存区域已经被释放),会导致未定义的风险
- 数组越界,⽐如创建⼀个⼤⼩为10的数组,如果通过指针访问到了 index = 11 的位置,这个时候是不是就越界了,访问了⼀个未知的内存空间。
- 类型不一致,指针类型与内存的值类型不⼀致,也是不安全的。
指针类型:
- typed pointer 指定数据类型指针(泛型指针)。
- raw pointer 未指定数据类型的指针(原⽣指针)。
Swift | Objctive-C | 备注 |
---|---|---|
UnsafePointer | const Pointee * | 指针可变,指向的内容不可变 |
UnsafeMutablePointer | Pointee * | 指针及指向的内容都可变 |
UnsafeRawPointer | const void * | 指针指向的内存区域未定 |
UnsafeMutableRawPointer | void * | 指针指向的一块连续的内存区域 |
UnsafeBufferPointer | const Pointee * | 指针指向的一块连续的内存区域 |
UnsafeMutableBufferPointer | Pointee * | 指针指向的一块连续可变的内存区域 |
UnsafeRawBufferPointer | const void * | 指针指向的一块连续的内存区域 |
UnsafeMutableRawBufferPointer | void * | 指针指向的一块连续可变的内存区域 |
1.1 原生指针
原⽣指针是指当前指针未绑定到了具体的类型。
// 指针操作
let p = UnsafeMutableRawPointer.allocate(byteCount: 32, alignment: 8)
print(MemoryLayout<Int>.stride) // 内存对齐后的步长
print(MemoryLayout<Int>.size) // 当前类型的大小
print(MemoryLayout<Int>.alignment) // 内存对齐方式
for i in 0...4 {
p.advanced(by: MemoryLayout<Int>.stride * i).storeBytes(of: i, as: Int.self)
}
for i in 0...4 {
let value = p.load(fromByteOffset: i * 8, as: Int.self)
print("\(i) - \(value)")
}
1.2 泛型指针
泛型指针是指当前指针已经绑定到了具体的类型。
// 通过指针属性 pointee 修改值
var age: Int = 18
age = withUnsafePointer(to: &age) {
ptr in
print(ptr.pointee + 12)
return ptr.pointee
}
print(age)
// 通过指针属性 pointee 修改值
let ptr = UnsafeMutablePointer<Int>.allocate(capacity: 8)
ptr.initialize(to: age)
print(ptr.pointee)
struct JHStruct {
var age: Int
var name: String
}
var jhPtr = UnsafeMutablePointer<JHStruct>.allocate(capacity: 2)
// 方式一:初始化
jhPtr[0] = JHStruct.init(age: 10, name: "张三")
jhPtr[1] = JHStruct.init(age: 10, name: "李四")
// 方式二:初始化
// jhPtr.initialize(to: JHStruct.init(age: 10, name: "张三"))
// jhPtr.advanced(by: MemoryLayout<JHStruct>.stride).initialize(to: JHStruct.init(age: 10, name: "李四"))