Swift 指针
Swift中的指针分为两类
- typed pointer 指定数据类型指针
- raw pointer 未指定数据类型的指针(原⽣指针)
raw pointer 在 Swift 中的表示是
UnsafeRawPointer
tyepd pointer
在 Swift 中的表示是
UnsafePointer<T>
我们来看⼀下 Swift 中的指针和 OC 中指针的对应关系:
Swift | Object-C | 说明 |
unsafePointer<T> | const T* | 指针及所指向内容都不可变 |
unsafeMutablePointer | T* | 指针及所指向内容都可改变 |
unsafeRowPointer | const void * | 指针指向未知类型 |
unsafeMutablePointer | void * | 指针指向未知类型 |
1.原始指针RawPointer使用
假设我们想在内存中存储连续 4 个整形的数据,我们如何使⽤ Raw Pointer 来做?
// byteCount:内存大小 alignment:字节对齐
var p = UnsafeMutableRawPointer.allocate(byteCount: 32, alignment: 8)
// 存储
for i in 0..<4 {
p.advanced(by: i*8).storeBytes(of: i+1, as: Int.self)
}
// 取值
for i in 0..<4 {
let value = p.load(fromByteOffset: i*8, as: Int.self)
print("index = \(i),value = \(value)")
}
p.deallocate()
2.typePointer使用 1
var age = 18
获取age地址 withUnsafePointer不可变指针 withUnsafePointer的返回值是 unSafePointer,意味着我们不能直接修改值, 此刻b的值
var pp = withUnsafePointer(to: &age) { ptr in
return ptr
}
print(pp.pointee)
//withUnsafeMutablePointer的返回值是 unSafeMutablePointer,意味着我们可以直接修改值
let pp = withUnsafeMutablePointer(to: &age) { ptr in
ptr.pointee += 12
}
print(age)
typePointer使用2
// 创建 2个连续空间 2*8字节
var mutPointer = UnsafeMutablePointer<Int>.allocate(capacity: 2)
// 初始化
mutPointer.initialize(to: 18)
print(mutPointer.pointee)
//3、下⾯两个成对调⽤,管理内存
mutPointer.deinitialize(count: 2)
mutPointer.deallocate()
demo1 指针类型绑定
struct HeadObject {
var kind: UnsafeRawPointer
var strongref: uint32
var unownedRef: uint32
}
struct lg_swift_class {
var kind: UnsafeRawPointer
var superClass: UnsafeRawPointer
var cachedata1: UnsafeRawPointer
var cachedata2: UnsafeRawPointer
var data: UnsafeRawPointer
var flages: uint32
var instanceAddressOffset: uint32
var instanceSize: uint32
var flinstanceAlignMask: uint16
var reserved: uint16
var classSize: uint32
var classAddressOffset: uint32
var description: UnsafeRawPointer
}
class KZHTeacher {
var age = 18
}
1.withMemoryRebound : 临时更改内存绑定类型
2.bindMemory(to: Capacity:) : 更改内存绑定的类型,如果之前没有绑定,那么就是⾸次绑定;如果绑 定过了,会被重新绑定为该类型。
3.assumingMemoryBound: 假定内存绑定,这⾥是告诉编译器:哥们我就是这种类型,你不要检查我了。
// 实例变量内存地址
var theacher = KZHTeacher()
// 所有权转换 返回 UnsafeMutableRawPointer
var mutPoiner = Unmanaged.passUnretained(theacher as AnyObject).toOpaque()
// 将mutPoiner 内存 绑定到headObject 返回 UnsafeMutablePointer
var headPointer = mutPoiner.bindMemory(to: HeadObject.self, capacity: 1)
// 将headpointer.kind内存 绑定到 swift_class
var swiftPointer = headPointer.pointee.kind.bindMemory(to: lg_swift_class.self, capacity: 1);
print(swiftPointer.pointee)
demo2 指针类型转换
var tul = (10,20)
func makePointer(_ p: UnsafePointer<Int>) {
print(p.pointee)
}
withUnsafePointer(to: &tul) { (tulPointer: UnsafePointer<(Int, Int)>) in
// 不能直接传 tulpointer 类型不配对, 因tulpointer已经绑定过 (int, int)类型,需要转成原始指针 再用 assumingMemoryBound假设绑定
let tulP = UnsafeRawPointer(tulPointer).assumingMemoryBound(to: Int.self)
makePointer(tulP)
}