UnsafeMutablePointer到Array元素

时间:2018-02-26 10:22:52

标签: ios swift macos unsafemutablepointer

UnsafeMutablePointer<Int>
  

错误:无法使用类型(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 } } 的初始值设定项

为什么后者不编译?这里有什么我想念的吗?

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

    OrderedCollection subclass: Stack [
   <shape: #inherit>
   pop [
      |lastElement|
      lastElement := self last.
      self removeLast.
      ^lastElement
   ]

   push: value[
      self addLast: value.
   ]

]

如何达到上述预期效果?

1 个答案:

答案 0 :(得分:6)

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

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

let ptr2 = UnsafeMutablePointer(&a) + index

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

array[1] = 2

相当于:

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

这意味着指向Array的指针在非常受控制的情况下(例如在withUnsafeMutableBufferPointer块内)无意义。

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

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]