Swift-06.指针(UnsafePointer)

Swift中也有专门的指针类型,这些都被定性为“Unsafe”(不安全的)。
常见的有以下4种类型:
  • UnsafePointer类似于 const Pointee *
  • UnsafeMutablePointer 类似于 Pointee *
  • UnsafeRawPointer 类似于 const void *
  • UnsafeMutableRawPointer 类似于 void *
    var age = 10
    func test1(_ ptr: UnsafeMutablePointer) {
        ptr.pointee += 10 
    }
    func test2(_ ptr: UnsafePointer) { 
        print(ptr.pointee)
    }
    test1(&age)
    test2(&age) // 20
    print(age) // 20

    var age = 10
    func test3(_ ptr: UnsafeMutableRawPointer) {
        ptr.storeBytes(of: 20, as: Int.self) 
    }
    func test4(_ ptr: UnsafeRawPointer) { 
        print(ptr.load(as: Int.self))
    }
    test3(&age)
    test4(&age) // 20
    print(age) // 20
  • 获得指向某个变量的指针:
var age = 11
var ptr1 = withUnsafeMutablePointer(to: &age) { $0 } 
var ptr2 = withUnsafePointer(to: &age) { $0 } 
ptr1.pointee = 22
print(ptr2.pointee) // 22
print(age) // 22

var ptr3 = withUnsafeMutablePointer(to: &age) { UnsafeMutableRawPointer($0) } 
var ptr4 = withUnsafePointer(to: &age) { UnsafeRawPointer($0) } 
ptr3.storeBytes(of: 33, as: Int.self)
print(ptr4.load(as: Int.self)) // 33
print(age) // 33
  • 获得指向堆空间实例的指针:
// UnsafeRawPointer(bitPattern:)函数用来生成指向某一地址的指针
var ptr = UnsafeRawPointer(bitPattern: 0x100001234)

class Person {}
// 类似于 *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(heapPtr!)
  • 创建指针:
    • 非泛型
     // 创建
     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)
    
     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)) // 11
     print(ptr.advanced(by: 8).load(as: Int.self)) // 22 
     // 销毁
     ptr.deallocate()
    
    • 泛型
      基础数据类型:
    var ptr = UnsafeMutablePointer.allocate(capacity: 3) 
     ptr.initialize(to: 11)
     // successor()后继, 表示向后走长度个字节
     ptr.successor().initialize(to: 22) 
     ptr.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
     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.allocate(capacity: 3) 
     ptr.initialize(to: Person(age: 10, name: "Jack"))
     (ptr + 1).initialize(to: Person(age: 11, name: "Rose")) 
     (ptr + 2).initialize(to: Person(age: 12, name: "Kate"))
     // Jack deinit
     // Rose deinit
     // Kate deinit 
     ptr.deinitialize(count: 3) 
     ptr.deallocate()
    
  • 指针之间的转换
     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.self).pointee) // 11
     print(unsafeBitCast(ptr + 8, to: UnsafePointer.self).pointee) // 22.0 
     ptr.deallocate()
    
     // unsafeBitCast是忽略数据类型的强制转换,不会因为数据类型的变化而改变原来的内存数据 
     // 类似于C++中的reinterpret_cast
    
     class Person {}
     var person = Person()
     var ptr = unsafeBitCast(person, to: UnsafeRawPointer.self) 
     print(ptr)
    
  • 关于指针的强制类型转换可参考这篇

你可能感兴趣的:(Swift-06.指针(UnsafePointer))