Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers Swift从UnsafemeutablePointer获取值<;无效>;使用非安全指针<;字符串>;_Pointers_Swift_Reference_Dereference - Fatal编程技术网

Pointers Swift从UnsafemeutablePointer获取值<;无效>;使用非安全指针<;字符串>;

Pointers Swift从UnsafemeutablePointer获取值<;无效>;使用非安全指针<;字符串>;,pointers,swift,reference,dereference,Pointers,Swift,Reference,Dereference,我试图将unsafemeutablepointer类型的contextInfo传递到UISaveVideoAtPathToSavedPhotosAlbum,并在回调函数中使用它。由于某些原因,当我在回调函数中时,我无法使用UnsafePointer(x.memory以字符串形式访问contextInfo 我很确定我错过了一些简单的东西,但我花了很多时间试图弄明白这一点 下面是我尝试过的一些代码 下面的代码可以工作 var testStr:String = "hello" takesAMutabl

我试图将
unsafemeutablepointer
类型的
contextInfo
传递到
UISaveVideoAtPathToSavedPhotosAlbum
,并在回调函数中使用它。由于某些原因,当我在回调函数中时,我无法使用
UnsafePointer(x.memory
以字符串形式访问
contextInfo

我很确定我错过了一些简单的东西,但我花了很多时间试图弄明白这一点

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

下面的代码可以工作

var testStr:String = "hello"
takesAMutableVoidPointer(&testStr)

func takesAMutableVoidPointer(x: UnsafeMutablePointer<Void>){
    var pStr:String = UnsafePointer<String>(x).memory
    println("x = \(x)")
    println("pStr = \(pStr)")
}
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)")
    }
}
在此方面的任何帮助都将不胜感激

谢谢

更新

Rintaro评论说testStr需要是顶级的,但是下面的代码可以工作

var testStr:String = "hello"
takesAMutableVoidPointer(&testStr)

func takesAMutableVoidPointer(x: UnsafeMutablePointer<Void>){
    var pStr:String = UnsafePointer<String>(x).memory
    println("x = \(x)")
    println("pStr = \(pStr)")
}
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)")
    }
}
导入UIKit
类ViewController:UIViewController{
重写func viewDidLoad(){
super.viewDidLoad()
//加载视图后,通常从nib执行任何其他设置。
var testStr:String=“你好”
takesAMutableVoidPointer(&testStr)
}
重写函数didReceiveMemoryWarning(){
超级。我收到了记忆警告()
//处置所有可以重新创建的资源。
}
func takesAMutableVoidPointer(x:unsameutablepointer){
var answer=UnsafePointer(x).memory
println(“x=\(x)”)
println(“答案=\(答案)”)
}
}

我尽量不使用全局变量,除非我必须这样做。我可能不得不这样做,但由于我能够执行上述代码,似乎我不需要使用全局变量。

如OP comments中所述,
testStr
已被释放

有没有办法强制保留函数中创建的变量?然后稍后再发布

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

无论如何,请尝试使用Playway或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()
<代码>导入基础 func foo(){ var str:NSString=“你好,世界” 让ptr=UnsafePointer(Unmanaged.passRetained(str.toOpaque()) 酒吧(ptr) } 功能条(v:非安全指针){ let at=发送时间( 现在发送时间, Int64(2.0*双精度(纳秒/秒)) ) 调度\u之后(在,调度\u获取\u主队列(){ 巴兹(五) } } func baz(v:UnsafePointer){ println(“通知”) 让str=Unmanaged.fromovaque(COpaquePointer(v)).takeRetainedValue() println(“信息:\(str)”) } foo() println(“已启动”) 调度_main()
  • Unmanaged.passRetained(str)
    增加保留计数
  • Unmanaged.from不透明(…).takeRetainedValue()
    将其递减,然后提取对象

我认为,使用纯Swift
字符串是不可能的。因为
String
struct
并在堆栈内存中分配。它的缓冲区可能是在堆中分配的,但我们不能直接访问它。

您在哪里声明
testStr
?它需要静态分配。因此,我认为它应该是顶级的,我可以在一个函数中定义testStr,然后将它的引用传递给另一个函数,并在另一个函数中获取引用的内容。这已经奏效了。我相信这意味着它不必是“顶级的”。但我可能不明白你所说的“顶级”是什么意思。问题是,使用UISaveVideoAtPathToSavedPhotosAlbum时,它不起作用。调用该函数。它进入函数。我甚至可以打印内存地址,但无法获取内存地址的内容。您更新的代码执行同步调用。在这种情况下,
testStr
将保留在内存中,直到
viewDidLoad
方法结束。但是,
UISaveVideoAtPathToSavedPhotosAlbum
异步通知回调,
testStr
此时已被释放。哦,好的,这是有意义的。有没有办法强制保留函数中创建的变量?然后稍后再发布?我这样问是因为在obj-c中,我能够在函数中创建一个
NSString*
变量,然后将其作为contextInfo参数传递给
UISaveVideoAtPathToSavedPhotosAlbum
。不过我确实把它演成了
(\uu bridge void*)
。我不认为这对变量的保留有任何影响,但我不确定。谢谢!我真的很感谢你的帮助。我必须承认,似乎有点令人不安的是,如果不使用全局变量或像上面那样的“跳转”来保留变量,就无法在swift中将contextInfo传递给UISaveVideoAtPathToSavedPhotosAlbum。
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()