美文网首页
Swift十六(1: 内存访问冲突,2: 指针)

Swift十六(1: 内存访问冲突,2: 指针)

作者: 看谷秀 | 来源:发表于2022-07-18 16:29 被阅读0次

    1 内存访问冲突
    2 swift指针

    一: 内存访问冲突

    内存访问冲突会在两个访问满足下列条件时发生:
    至少一个是写入操作
    它们访问的是同一块内存
    它们的访问时间重叠(比如在同一个函数内)

    // 不存在内存访问冲突
    func plus(_num: inoutInt) -> Int {num + 1}
    var number = 1  
    number = plus(&number) // 正常输入输出参数, 做+ 1 操作
    
    // 存在访问冲突
    // Simultaneous accesses to 0x0, but modification requires exclusive access 
    // 同时访问0x0,但修改需要独占访问
    var step=1 
    func increment(_num: inoutInt){num += step}
    increment(&step)
    // num += step 同时调用了, step变量的setter方法 和getter方法 访问冲突
    
    // 解决内存访问冲突
    var copyOfStep = step 
    increment(&copyOfStep) // 修改copyOfStep 变量
    step = copyOfStep // 重新赋值step
    
    二: 指针类型

    定义:
    Swift中也有专门的指针类型,这些都被定性为“Unsafe”(不安全的),常见的有以下4种类型
    UnsafePointer<Pointee> 类似于 const Pointee * p UnsafeMutablePointer<Pointee> 类似于 Pointee * p
    UnsafeRawPointer 类似于 const void * p
    UnsafeMutableRawPointer 类似于 void *

    1 UnsafePointer & UnsafeMutablePointer

    var age = 10
    func test1(_ ptr: UnsafeMutablePointer<Int>) { // 代表需要传个地址, 读写
       ptr.pointee += 10     // 效果类似inout输入输出参数
    }
    func test2(_ ptr: UnsafePointer<Int>) { // 代表需要传个地址, 只读
       print(ptr.pointee)
    }
    test1(&age)
    test2(&age) // 20
    print(age) // 20
    

    2 UnsafeRawPointer & UnsafeMutableRawPointer

    var age = 10
    func test3(_ ptr: UnsafeMutableRawPointer) {
       ptr.storeBytes(of: 20, as: Int.self) // 类似setter 写入
    }
    func test4(_ ptr: UnsafeRawPointer) {
       print(ptr.load(as: Int.self)) // 类似getter读取
    }
    test3(&age)
    test4(&age) // 20
    print(age) // 20
    

    3 指针的应用示例 stop.pointee对比break

    var arr = NSArray(objects: 11, 22, 33, 44)
    arr.enumerateObjects { (obj, idx, stop) in
    print(idx, obj)
    if idx == 2 { // 下标为2就停止遍历
        stop.pointee = true
    } }
    
    var arr = NSArray(objects: 11, 22, 33, 44)
    for (idx, obj) in arr.enumerated() {
    print(idx, obj)
    if idx == 2 {
       break
    } }
    

    4 获得指向某个变量的指针

    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
    
    let ptr6 = withUnsafeMutablePointer(to: &age) { (p) -> UnsafeMutablePointer in
        return   p // ptr1 原版写法, 返回值p的类型和参数闭包返回值类型要一致
    }
    ptr6.pointee = 40
    print(age)
    // 返回 withUnsafeMutablePointer / withUnsafePointer类型
    
    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
    // 返回 UnsafeMutableRawPointer / UnsafeRawPointer类型
    

    相关文章

      网友评论

          本文标题:Swift十六(1: 内存访问冲突,2: 指针)

          本文链接:https://www.haomeiwen.com/subject/rogrirtx.html