Swift<Void> 使用 UnsafePointer 从 UnsafeMutablePointer <String>获取值



我正在尝试将类型为UnsafeMutablePointer<Void>contextInfo传递给UISaveVideoAtPathToSavedPhotosAlbum,并在回调函数中使用它。由于某些原因,当我在回调函数中时,无法使用UnsafePointer<String>(x).memorycontextInfo作为字符串访问。

我很确定我错过了一些简单的东西,但我已经花了很多小时试图弄清楚这一点。

下面是我尝试过的一些代码。

以下代码有效。

var testStr:String = "hello"
takesAMutableVoidPointer(&testStr)
func takesAMutableVoidPointer(x: UnsafeMutablePointer<Void>){
    var pStr:String = UnsafePointer<String>(x).memory
    println("x = (x)")
    println("pStr = (pStr)")
}

但是,以下代码不起作用。

var testStr:String = "hello"
if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(filePath){ //the filePath is compatible
    println("Compatible")
    //UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, nil, nil)
    UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, "video:didFinishSavingWithError:contextInfo:", &testStr)
}
else{
    println("Not Compatible")
}
func video(video: NSString, didFinishSavingWithError error:NSError, contextInfo:UnsafeMutablePointer<Void>){
    var pStr:String = UnsafePointer<String>(contextInfo).memory
    println("contextInfo = (contextInfo)")
    println("pStr = (pStr)")
}

一旦我到达以下线路:

var pStr:String = UnsafePointer<String>(contextInfo).memory

我一直得到以下错误:

Thread 1: EXC_BAD_ACCESS(code=1, address=0x0)

如有任何帮助,我们将不胜感激。

谢谢。

更新

Rintaro评论道,testStr需要是顶级的,但下面的代码是有效的。

import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        var testStr:String = "hello"
        takesAMutableVoidPointer(&testStr)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    func takesAMutableVoidPointer(x: UnsafeMutablePointer<Void>){
        var answer = UnsafePointer<String>(x).memory
        println("x = (x)")
        println("answer = (answer)")
    }
}

除非迫不得已,否则我尽量不使用全局变量。我可能不得不这样做,但由于我能够执行上面的代码,我似乎不需要使用全局变量了。

正如OP注释中所讨论的,testStr已经被释放。

是否有任何方法可以强制保留在函数中创建的变量?然后稍后发布?

这不是不可能,但我不知道这是最好的方法。

无论如何,试试Playground或OS X的"命令行工具"模板:

import Foundation
func foo() {
    var str:NSString = "Hello World"
    let ptr = UnsafePointer<Void>(Unmanaged<NSString>.passRetained(str).toOpaque())
    bar(ptr)
}
func bar(v:UnsafePointer<Void>) {
    let at = dispatch_time(
        DISPATCH_TIME_NOW,
        Int64(2.0 * Double(NSEC_PER_SEC))
    )
    dispatch_after(at, dispatch_get_main_queue()) {
        baz(v)
    }
}
func baz(v:UnsafePointer<Void>) {
    println("notified")
    let str = Unmanaged<NSString>.fromOpaque(COpaquePointer(v)).takeRetainedValue()
    println("info: (str)")
}

foo()
println("started")
dispatch_main()
  • Unmanaged<NSString>.passRetained(str)递增保留计数
  • Unmanaged<NSString>.fromOpaque(...).takeRetainedValue()将其递减,并提取对象

我认为,使用pureSwift String是不可能的。因为CCD_ 10是CCD_。也许它的缓冲区是在堆中分配的,但我们不能直接访问它。

最新更新