UnsafePointer、UnsafeRawPointer 的使用

//指针打印
po Unmanaged.passUnretained(person as AnyObject).toOpaque()

var age = 10

var ptr = withUnsafePointer(to: &age) { (p) -> UnsafePointer<Int> in
    return p
}
//等价
var ptr1 = withUnsafePointer(to: &age) { $0 }

//返回值:UnsafeRawPointer
var ptr2 = withUnsafePointer(to: &age) { UnsafeRawPointer($0) }
print(ptr2.load(as: Int.self))

//返回值:UnsafeRawPointer
var ptr3 = withUnsafeMutablePointer(to: &age) { UnsafeMutableRawPointer($0) }
ptr3.storeBytes(of: 33, as: Int.self) //age = 33

//模拟低层实现
func withUnsafePointe<Result, T>(to: UnsafePointer<T>, body: (UnsafePointer<T>) -> Result) ->Result {//body返回什么类型,withUnsafePointe就返回什么类型
    return body(to)
}

withUnsafePointe(to: &age) { $0 }

获取指针变量对象的内存地址
var person = Person(age: 10)
//person指针变量地址:0x0000000100009cca
var ptr4 = withUnsafePointer(to: &person) { UnsafeRawPointer($0) }

var personObjectAddress = ptr4.load(as: UInt.self)
var ptr5 = UnsafeMutableRawPointer(bitPattern: personObjectAddress);//UnsafeMutableRawPointer可失败初始化器(可选?)
//或者
ptr5 = unsafeBitCast(person, to: UnsafeMutableRawPointer.self)
print(ptr5!)//person对象堆空间内存地址:0x00000001038b9cc0
//创建指针 UnsafeMutableRawPointer
var ptr6 = malloc(16)
//前8个字节存
ptr6?.storeBytes(of: 10, as: Int.self)
//后8个字节存
ptr6?.storeBytes(of: 20, toByteOffset: 8, as: Int.self)
print((ptr6?.load(fromByteOffset: 8, as: Int.self))!)
//销毁
free(ptr6)

//创建指针
var ptr7 = UnsafeMutableRawPointer.allocate(byteCount: 16, alignment: 1)
ptr7.deallocate()
rawPointer 转换 泛型指针
//尝试转换
var ptr0 = ptr7.assumingMemoryBound(to: Int.self)
//强制转换(类似C++中的reinterpret_cast,忽略类型的强制转换,不会因为数类型的变化而改变原来的内存数据。二进制直接赋值强转。
//所以有风险,如果double数据强转int,得到的数据就不再是原来的数据)
ptr0 = unsafeBitCast(ptr7, to: UnsafeMutablePointer<Int>.self)//强制转换
print(ptr0.pointee)
var ptr8 = UnsafeMutablePointer<Int>.allocate(capacity: 3)
ptr8.initialize(to: 11)
ptr8.successor().initialize(to: 22)
ptr8.successor().successor().initialize(to: 33)

print(ptr.pointee) //11
print((ptr + 1).pointee)// 22
print((ptr + 2).pointee)// 33

print(ptr[0]) //11
print(ptr[1])// 22
print(ptr[2])// 33

//销毁
defer {//作用域结束是调用
    ptr8.deinitialize(count: 3) //调用了initialize,销毁同时也要调反初始化
    ptr8.deallocate()
}

推荐阅读更多精彩内容