Swift指针介绍



  • Swift版本: 4.0

    Swift 通过引用计数器来管理内存,但也提供了指针操作。

    有如下指针类型:

    • UnsafeMutablePointer
    • UnsafePointer
    • UnsafeRawPointer
    • UnsafeRawBufferPointer
    • UnsafeBufferPointer
    • UnsafeMutableBufferPointer

    说明:

    • 带Mutable表示内存中的数据可变,反之表示内存中的数据不可变

    • 带Raw表示指针指向的内存未分配具体的数据类型,反之指针指向的内存已分配具体的数据类型

    • 带Buffer表示用来处理Swift数组和指针

    代码示例

    • Mutable Pointer
    // 指向Int整数类型的指针
    var a = 98
    print("1: a = \(a)")
    printValueInt(ptr: &a)
    increaseValue(ptr: &a)
    print("2: a = \(a)")
    
    func increaseValue(ptr: UnsafeMutablePointer<Int>) {
        ptr.pointee += 1    // mutable类型: 可修改对应的value
    }
    
    func printValueInt(ptr: UnsafePointer<Int>) {
        print("ptr value = \(ptr.pointee)")   // 非mutable类型: 只读,不可修改
    }
    

    输出如下日志

    1: a = 98
    ptr value = 98
    2: a = 99
    
    • Raw Pointer
    var a = 98
    print("1: a = \(a)")
    convertRawPointer(ptr: &a)
    print("2: a = \(a)")
    
    func convertRawPointer(ptr: UnsafePointer<Int>) {
        let rawPtr = UnsafeRawPointer(ptr)  // UnsafePointer 转 UnsafeRawPointer
        print("convertRawPointer rawPtr = \(rawPtr)")
        let ptrInt = rawPtr.assumingMemoryBound(to: Int.self) // UnsafeRawPointer 转 UnsafePointer
        print("convertRawPointer ptrInt = \(ptrInt), value = \(ptrInt.pointee)")
    }
    

    输出如下内容

    1: a = 98
    convertRawPointer rawPtr = 0x00007ffee9d725e8
    convertRawPointer ptrInt = 0x00007ffee9d725e8, value = 98
    2: a = 98
    
    • Buffer Pointer
    // 指向数组(Int)的指针
    var testArrayInt = [10, 20, 30]
    handleArrayInt(ptr: &testArrayInt)
    print("testArrayInt = \(testArrayInt)")
    
    func handleArrayInt(ptr: UnsafeMutablePointer<Int>) {
        print("1: handleArrayInt ptr[1] = \(ptr[1])")
        ptr.advanced(by: 1).pointee = 99
        print("2: handleArrayInt ptr[1] = \(ptr[1])")
        
        let buffer = UnsafeBufferPointer(start: ptr, count: 3)
        // 转化为Buffer类型,进而遍历数组
        buffer.forEach {
            print("handleArrayInt print array element = \($0)")
        }
    }
    

    输出如下内容

    1: handleArrayInt ptr[1] = 20
    2: handleArrayInt ptr[1] = 99
    handleArrayInt print array element = 10
    handleArrayInt print array element = 99
    handleArrayInt print array element = 30
    testArrayInt = [10, 99, 30]
    
    • 自定义class类型指针
    class TestUser {
        var name: String
        var age: Int
        
        init(name: String, age: Int) {
            print("TestUser init")
            self.name = name
            self.age = age
        }
        
        deinit {
            print("TestUser deinit")
        }
    }
    
    var userPtr: UnsafeMutablePointer<TestUser>!
    userPtr = UnsafeMutablePointer<TestUser>.allocate(capacity: 1)
    print("allocate userPtr = \(userPtr)")
    userPtr.initialize(to: TestUser(name: "Cary1", age: 18))
    print("initialize userPtr = \(userPtr), value name = \(userPtr.pointee.name), age = \(userPtr.pointee.age)")
    userPtr.deinitialize()
    print("deinitialize userPtr = \(userPtr)")
    userPtr.deallocate(capacity: 1)
    userPtr = nil
    print("deallocate userPtr = \(userPtr)")
    

    输出如下内容

    allocate userPtr = Optional(0x0000604000005e30)
    TestUser init
    initialize userPtr = Optional(0x0000604000005e30), value name = Cary1, age = 18
    TestUser deinit
    deinitialize userPtr = Optional(0x0000604000005e30)
    deallocate userPtr = nil
    

    Demo源码

    https://github.com/CaryZheng/iOSTutorials


Log in to reply