我使用Int64
某些实例(在某些数组中正确存储并保留)对unsafeAddressOf
(在图形卡上)进行编码。
然后我想从我的Int64
回到我的实例。我设法从UnsafePointer<MyClass>
正确初始化了Int64
。
然后,我这样做:
let x = UnsafePointer<MyClass>.memory.
但是使用x
崩溃。
据我所知,考虑ARC,这是不安全和棘手的。但是,有没有办法在Swift中实现这一点,还是无助呢?
感谢。
答案 0 :(得分:0)
class C {
func foo() {
print("C")
}
}
var c = C()
let addr = unsafeAddressOf(c)
dump(addr)
/*
▿ UnsafePointer(0x7F86E942B230)
- pointerValue: 140217415807536
*/
let pC = withUnsafePointer(&c) { (p) -> UnsafePointer<C> in
return p
}
dump(pC)
/*
▿ UnsafePointer(0x10DE5B390)
- pointerValue: 4528124816
*/
dump(pC.memory)
/*
- C #0
*/
let opaquePointer = COpaquePointer(addr)
let unmanagedC = Unmanaged<C>.fromOpaque(opaquePointer)
dump(unmanagedC)
/*
▿ Swift.Unmanaged<C>
- _value: C #0
*/
// I still dont have an idea how to use it ...
哈,我知道了!
unmanagedC.takeUnretainedValue().foo() // prints C !
答案 1 :(得分:0)
正如您自己所说,您要做的事情非常不安全,并且可能有更安全的方法来解决您正在处理的任何问题,但这是一个完整的例子:
func getPointer<T:AnyObject>(obj : T) -> Int64
{
return unsafeBitCast(unsafeAddressOf(obj), Int64.self)
}
func recoverObject<T:AnyObject>(ptr : Int64) -> T
{
return Unmanaged<T>.fromOpaque(COpaquePointer(bitPattern: Int(ptr))).takeUnretainedValue()
}
class C {
var cID = 0
func foo() {
print("Instance of C, id = \(cID)")
}
}
class D {
var dID = 0
func foo() {
print("Instance of D, id = \(dID)")
}
}
let c : C = C()
let d : D = D()
c.cID = 123;
d.dID = 321;
let cPtr : Int64 = getPointer(c)
let dPtr : Int64 = getPointer(d)
c.cID *= 10
let c1 : C = recoverObject(cPtr)
let d1 : D = recoverObject(dPtr)
c1.foo()
d1.foo()
输出结果为:
Instance of C, id = 1230
Instance of D, id = 321
感谢user3441734提供了一些有用的提示!注意泛型的使用。获取&#34;指针的功能&#34;并且取消引用它应该适用于任何类(但不会使用结构)。
就更安全的方式而言,答案取决于你正在做的事情的背景。为什么不能在需要实例的地方访问实例数组而不是通过Int64获取它们?如果数组实际上是由第三方库中的(Objective-)C代码维护的,那么由于内存对齐等原因可能会出现其他问题。有可能编写将实例返回给Swift代码的C代码。更安全的方式。
如果答案由于某种原因无效,请告诉我更多详细信息。