【Swift】UnsafePointer等指针

指针相关,关键字

  • UnsafePointer类似于 const Pointee *
  • UnsafeMutablePointer 类似于 Pointee *
  • UnsafeRawPointer 类似于 const void *
  • UnsafeMutableRawPointer 类似于 void *
  • UnsafeBufferPointer
  • UnsafeMutableBufferPointer
  • unsafeBitCast

UnsafePointer/UnsafeMutablePointer

  • 打印属性指针
var nickname = "alexluan"
func test1(_ ptr: UnsafeMutablePointer<String>) {
    print(ptr.pointee)
    print(ptr)
}

func test2(_ ptr: UnsafePointer<String>) {
    print(ptr.pointee)
    print(ptr)
}

test1(&nickname)
test2(&nickname)
print(nickname)
//alexluan
//0x000000010607e090
//alexluan
//0x000000010607e090
//alexluan

打印变量指针

var nickname = "alexluan"
var ptr1 = withUnsafeMutablePointer(to: &nickname) { $0 }
var ptr2 = withUnsafePointer(to: &nickname) { $0 }
ptr1.pointee = "22"
print(ptr2.pointee)
print(nickname)

print(ptr1)
print(ptr2)

var ptr3 = withUnsafeMutablePointer(to: &nickname) { UnsafeMutableRawPointer($0) }
var ptr4 = withUnsafePointer(to: &nickname) { UnsafeRawPointer($0) }
ptr3.storeBytes(of: "33", as: String.self)
print(ptr4.load(as: String.self))
print(nickname)

print(ptr3)
print(ptr4)
//22
//22
//0x00000001118bb090
//0x00000001118bb090
//33
//33
//0x00000001118bb090
//0x00000001118bb090

UnsafeRawPointer

  • 简单测试
// UnsafeRawPointer(bitPattern:)函数用来生成指向某一地址的指针
var ptr0 = UnsafeRawPointer(bitPattern: 0x000060000170c1a0)

class Person {
    var name: String = "alexluan"
}
// 类似于 *p = person
var person = Person()
// p = &person, p是person变量的地址值
var ptr = withUnsafePointer(to: &person) { UnsafeRawPointer($0) }
// ptr.load(as: UInt.self) 类似于 *p, 取出地址中存储的值,也就是Person实例在堆上的地址值
var heapPtr = UnsafeRawPointer(bitPattern: ptr.load(as: UInt.self))
print(ptr0)
print(ptr)
print(heapPtr!)

print(ptr.load(as: Person.self).name)

//Optional(0x000060000170c1a0)
//0x000000010361a4d8
//0x00006000009d3b00
//alexluan
  • 非泛型
var ptr = malloc(16)
// 存
ptr?.storeBytes(of: 11, as: Int.self)
ptr?.storeBytes(of: 22, toByteOffset: 8, as: Int.self)
// 取
print((ptr?.load(as: Int.self))!) // 11
// fromByteOffset: 地址偏移
print((ptr?.load(fromByteOffset: 8, as: Int.self))!) // 22
// 销毁
free(ptr)

//11
//22
var ptr = UnsafeMutableRawPointer.allocate(byteCount: 16, alignment: 1)
ptr.storeBytes(of: 11, as: Int.self)
// advanced: 也是地址偏移
ptr.advanced(by: 8).storeBytes(of: 22, as: Int.self)
print(ptr.load(as: Int.self))
print(ptr.advanced(by: 8).load(as: Int.self))
// 销毁
ptr.deallocate()

//11
//22
  • 泛型
var ptr = UnsafeMutablePointer<String>.allocate(capacity: 3)
ptr.initialize(to: "11")
// successor()后继, 表示向后走<String>长度个字节
ptr.successor().initialize(to: "22000008")
ptr.successor().successor().initialize(to: "33")
print(ptr.pointee) // 11
// 这里的 + 指的是指针的加,步长为<String>长度个字节
print((ptr + 1).pointee) // 22000008
print((ptr + 2).pointee) // 33

ptr[0] = "alexluan"
print(ptr[0]) // alexluan
print(ptr[1]) // 22000008
print(ptr[2]) // 33
ptr.deinitialize(count: 3)
ptr.deallocate()
  • 对象
class Person {
    var age: Int
    var name: String
    init(age: Int, name: String) {
        self.age = age
        self.name = name
    }
    deinit { print(name, "deinit") }
}
var ptr = UnsafeMutablePointer<Person>.allocate(capacity: 3)
ptr.initialize(to: Person(age: 18, name: "alex"))
(ptr + 1).initialize(to: Person(age: 19, name: "eric"))
(ptr + 2).initialize(to: Person(age: 20, name: "phoenix"))
ptr.deinitialize(count: 3)
ptr.deallocate()

// alex deinit
// eric deinit
// phoenix deinit

指针之间的转换

var ptr = UnsafeMutableRawPointer.allocate(byteCount: 16, alignment: 1)
ptr.assumingMemoryBound(to: Int.self).pointee = 11
(ptr + 8).assumingMemoryBound(to: Double.self).pointee = 22.0

// 只改变类型,而不改变其值
//(值指的是二进制数据,也就是你告诉计算机这是什么类型,计算机就按什么类型解读这些二进制数据)
print(unsafeBitCast(ptr, to: UnsafePointer<Int>.self).pointee) // 11
print(unsafeBitCast(ptr + 8, to: UnsafePointer<Double>.self).pointee) // 22.0
ptr.deallocate()

  • unsafeBitCast 用法(以后尝试)
class User {}
var user = User()
var ptr = unsafeBitCast(user, to: UnsafeRawPointer.self)
print(ptr)
var ptr0 = UnsafeMutablePointer(&user)
print(ptr0)
var ptr1 = UnsafeMutablePointer(&user)
print(ptr1)
//0x00006000010b8050
//0x00000001036293e0
//0x00000001036293e0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值