【发布时间】:2017-09-19 21:51:35
【问题描述】:
我正在尝试从使用Unmanaged.passUnretained().toOpaque() 获得的UnsafeMutableRawPointer 中获取UnsafeMutablePointer:
class C { var foo = 42, bar = "bar" }
let c = C()
let rawPointer = Unmanaged.passUnretained(c).toOpaque()
let pointer = rawPointer.bindMemory(to: C.self, capacity: 1)
let pointee = pointer.pointee
print(pointee.foo) // EXC_BAD_ACCESS
这是一些 LLDB 输出,我觉得这很奇怪,因为 pointer 中的一切似乎都很好,直到我询问它的 pointee:
(lldb) frame variable -L c
scalar: (memtest2.C) c = 0x0000000101d00030 {
0x0000000101d00040: foo = 42
0x0000000101d00048: bar = "bar"
}
(lldb) frame variable -L rawPointer
0x00000001005e2e08: (UnsafeMutableRawPointer) rawPointer = {
scalar: _rawValue = 0x0000000101d00030 {
0x0000000101d00040: foo = 42
0x0000000101d00048: bar = "bar"
}
}
(lldb) frame variable -L pointer
0x00000001005e2e10: (UnsafeMutablePointer<memtest2.C>) pointer = 0x0000000101d00030
(lldb) frame variable -L pointer._rawValue
scalar: (memtest2.C) pointer._rawValue = 0x0000000101d00030 {
0x0000000101d00040: foo = 42
0x0000000101d00048: bar = "bar"
}
(lldb) frame variable -L pointee
0x00000001005e2e18: (memtest2.C) pointee = 0x00000001005b65d8 {
0x00000001005b65e8: foo = 140736790071664
0x00000001005b65f0: bar = ""
}
我也试过assumingMemoryBound(to:)、load(as:),或者干脆:
let pointer = UnsafePointer<C>(bitPattern: Int(bitPattern: rawPointer))!
print(pointer.pointee.foo) // EXC_BAD_ACCESS
但我总是收到这个 EXC_BAD_ACCESS 错误。这是怎么回事?
【问题讨论】:
-
试试
let obj = Unmanaged<C>.fromOpaque(rawPointer).takeUnretainedValue();print(obj.foo)。 -
@OOPer 我的最终目标不是访问
C实例,而是真正从原始实例中获取有效的类型化指针。 -
那我无法理解你的最终目标。无论如何,只有当
rawPointer是指向C实例的引用的指针时,您的代码才有效,Unmanaged.passUnretained(c).toOpaque()不成功。 -
let obj = Unmanaged<C>.fromOpaque(rawPointer).takeUnretainedValue()is 是指向 C 实例的有效类型指针,是您问题的正确答案。比较stackoverflow.com/questions/33294620/…。 -
@MartinR
takeUnretainedValue()在我想获得Unsafe[Mutable]Pointer<C>实例时返回c实例(来自UnsafeMutableRawPointer)。