Swift получить значение от UnsafeMutablePointer с помощью UnsafePointer
Я пытаюсь передать contextInfo
типаUnsafeMutablePointer<Void>
to UISaveVideoAtPathToSavedPhotosAlbum
и использовать его в функции обратного вызова. По какой-то причине я не могу получить доступ contextInfo
в строку с помощью UnsafePointer<String>(x).memory
когда я в функции обратного вызова.
Я уверен, что это что-то простое, чего мне не хватает, но я потратил много часов, пытаясь понять это.
ниже приведен код, который я пробовал.
следующий код работает.
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)")
}
}
Я пытаюсь не использовать глобальные переменные, если мне не нужно. Я возможно, придется, но поскольку я могу выполнить приведенный выше код, кажется, что мне не нужно использовать глобальную переменную.
1 ответов
как обсуждалось в комментариях OP,testStr
уже освобожден.
есть ли способ принудительно сохранить переменную, которая была создана в функции? Тогда отпустите его позже?
это не невозможно, но я не знаю, что это лучший способ сделать это.
в любом случае, попробуйте это с игровой площадкой или 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()
уменьшает его и извлекает объект.
Я думаю, используя чисто Свифт String
- это невозможно. потому что String
is struct
и выделяется память в стеке. Возможно, буфер его выделяется в куче, но мы не можем получить к нему прямой доступ.