Swift Manual Memory Management (Pointer)

Type Pointer

UnsafePointer, UnsafeMutablePointer

func withUnsafePointer(to value: T, _ body: (UnsafePointer) throws -> Result) rethrows -> Result
func withUnsafePointer(to value: inout T, _ body: (UnsafePointer) throws -> Result) rethrows -> Result
func withUnsafeMutablePointer(to value: inout T, _ body: (UnsafeMutablePointer) throws -> Result) rethrows -> Result

可以通过以上函数获取相应的 UnsafePointer

let number0 = 1
let number1 = withUnsafePointer(to: number0) { $0.pointee }
let number2 = withUnsafePointer(to: &number0) { $0.pointee }

var number = 1
withUnsafeMutablePointer(to: &number) { $0.pointee = 2 }

UnsafePointer 的 pointee 是对应类型的值

但需要注意,不可以将 block 中的 pointer 返回用作它用,即

let number = 1
let pointer = withUnsafePointer(to: &count) { $0 }

是错误的,swift 中仅保证 UnsafePointer 在 block 中的生命周期正常,在 block 外使用其结果不可预测

应这样使用

func printValue(pointer : UnsafePointer) {
    print("\(pointer.pointee)")
}

let count = 1

// 正确
withUnsafeMutablePointer(to: count) { printValue($0) }

// 错误
let pointer = withUnsafeMutablePointer(to: count) { $0 }
printValue(pointer)

另外,在函数的调用中可以这样使用

func change(pointer : UnsafeMutablePointer, to value: Int) {
    pointer.pointee = value
}

var count = 1;
chang(&count, 2);

但直接使用

let count = 1
let pointer = &count

是错误的

最后可以使用 withMemoryRebound 转换 UnsafePointer 的类型

let wcnm : Int8 = -1
withUnsafePointer(to: wcnm) {
    $0.withMemoryRebound(to: UInt8.self, capacity: 1) { print("\($0.pointee)") }
}

UnsafeBufferPointer, UnsafeMutableBufferPointer

func withUnsafeBufferPointer((UnsafeBufferPointer.Element>) -> R) -> R
func withUnsafeMutableBufferPointer((inout UnsafeMutableBufferPointer.Element>) -> R) -> R

通过 Array 的以上函数,可以获得相应的 UnsafeBufferPointer

let array = [1, 2, 3]
let first = array.withUnsafeBufferPointer { $0.baseAddress!.pointee }
let second = array.withUnsafeBufferPointer { $0[1] }

var array = [1, 2, 3]
array.withUnsafeMutableBufferPointer { $0.baseAddress!.pointee = 4}
array.withUnsafeMutableBufferPointer { $0[1] = 5 }

通过 baseAddress 或是 索引 访问其中的值

同样只可在 block 中使用 UnsafeBufferPointer 和 UnsafeMutableBufferPointer

需要注意的是
let array = [1, 2, 3]
&array 代表的是 UnsafePointer<[Int]> 需不是 UnsafeBufferPointer

let count = 1
withUnsafePointer(to: count {
    print("\(UnsafeBufferPointer(start: $0, count: 1)[0])")
}

另可以通过 UnsafePointer 生成 UnsafeBufferPointer

你可能感兴趣的:(Swift Manual Memory Management (Pointer))