jbl*_*ixr 2 macos ios swift 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
Run Code Online (Sandbox Code Playgroud)
error:无法为类型
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
}
}
Run Code Online (Sandbox Code Playgroud)
如何达到上述预期效果?
请注意,这些都不是创建UnsafeMutablePointer的有效方法.Swift可以在最后一次引用后立即释放a,所以当你使用这些指针时,它们可能无效.你想要的工具是a.withUnsafeMutableBufferPointer.
也就是说,这里的正确语法是:
let ptr2 = UnsafeMutablePointer(&a) + index
Run Code Online (Sandbox Code Playgroud)
查看更新后的代码,没有办法在Array上有意义.我想你假设Arrays是引用类型.他们是价值类型.没有办法改变一块numbers.对它的任何更改都会用完全不同的数组替换整个数组.Swift有一些聪明的写时复制技巧可以提高效率,实际上它可能实际上并没有取代整个数组,但你应该编程就像它一样.您应该考虑以下行:
array[1] = 2
Run Code Online (Sandbox Code Playgroud)
相当于:
array = <a new array that is identical, but element 1 has been replaced by 2>
Run Code Online (Sandbox Code Playgroud)
这意味着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]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
691 次 |
| 最近记录: |