从'unsafeAddressOf'获取实例

时间:2015-11-20 17:07:33

标签: swift2

我使用Int64某些实例(在某些数组中正确存储并保留)对unsafeAddressOf(在图形卡上)进行编码。

然后我想从我的Int64回到我的实例。我设法从UnsafePointer<MyClass>正确初始化了Int64

然后,我这样做:

let x = UnsafePointer<MyClass>.memory. 

但是使用x崩溃。

据我所知,考虑ARC,这是不安全和棘手的。但是,有没有办法在Swift中实现这一点,还是无助呢?

感谢。

2 个答案:

答案 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代码。更安全的方式。

如果答案由于某种原因无效,请告诉我更多详细信息。