ios - 指向数组元素的 UnsafeMutablePointer

标签 ios swift macos unsafemutablepointer

var a = [1,2,3]
let ptr1 = UnsafeMutablePointer<Int>(&a[0]) //works fine

let index = 0
let ptr2 = UnsafeMutablePointer<Int>(&a[index]) //compiler throws error

error: cannot invoke initializer for type UnsafeMutablePointer<Int> with an argument list of type (inout Int)

为什么后一个不编译?我在这里遗漏了什么吗?


我想像下面的代码片段那样做。

class Holder {
    var numbers: [Int] = [1,2,3,4]
    var modifier: Modifier

    init(index: Int) {
       self.modifier = Modifier(UnsafeMutablePointer(&self.numbers) + index)
    }

}

class Modifer {
  var ptr: UnsafeMutablePointer<Int>

  init(_ ptr: UnsafeMutablePointer<Int>) {
     self.ptr = ptr
  }

  func change(to: Int) {
     self.ptr.pointee = to
    // expected the change to be reflected in numbers array
    // but as Rob Napier said it became invalid and throws EXC_BAD_ACCESS
  }
}

如何才能达到上述预期效果?

最佳答案

请注意,这些都不是创建 UnsafeMutablePointer 的有效方法。 Swift 可以在最后一次引用 a 之后立即释放它,所以当你使用这些指针时,它们可能已经无效了。您需要的工具是 a.withUnsafeMutableBufferPointer

也就是说,这里的正确语法是:

let ptr2 = UnsafeMutablePointer(&a) + index

查看您更新后的代码,这在 Array 上没有任何意义。我认为您假设数组是引用类型。它们是值类型。没有办法改变一段 numbers。对它的任何更改都会用一个完全不同的数组替换整个数组。 Swift 有一些聪明的写时复制技巧来提高效率,实际上它可能不会实际上替换整个数组,但您应该像它那样进行编程。您应该考虑以下行:

array[1] = 2

相当于:

array = <a new array that is identical, but element 1 has been replaced by 2>

这意味着指向 Array 的指针在非常受控的情况之外(例如在 withUnsafeMutableBufferPointer block 内)是没有意义的。

你想要的是更像这样的东西:

class Holder {
    var numbers: [Int] = [1,2,3,4]
    private(set) var modifier: ((Int) -> ())! // ! is an artifact of capturing self in init

    init(index: Int) {
        self.modifier = { [weak self] in self?.numbers[index] = $0 }
    }
}

let holder = Holder(index: 2)
holder.numbers  // [1, 2, 3, 4]
holder.modifier(0)
holder.numbers  // [1, 2, 0, 4]

关于ios - 指向数组元素的 UnsafeMutablePointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48986177/

相关文章:

c - 为什么 32 位内核可以运行 64 位二进制文​​件?

ios - 更改 NSFetchedResultsController 的获取请求和重新加载表数据的方法

ios - 如何在 LLDB 中调试成员变量(即 Array、Dictionary)?

ios - 准备在按下按钮时 segue 不发送信息

Java Jar 和 Classpath 问题

ios - OSX 上的 AWS MQTT

iphone - xCode Organizer 中的分发证书

ios - Hackerrank 新年困惑 Swift

ios - swift如何在特定时间设置通知

ios - 如何在同类节点之间不发生碰撞