Swift gets value from UnsafeMutablePointer <Void> using UnsafePointer <String>

I am trying to pass a contextInfo type UnsafeMutablePointer<Void> to UISaveVideoAtPathToSavedPhotosAlbum and use it in a callback function. For some reason, I cannot access contextInfo as a string using UnsafePointer<String>(x).memory when I enter the callback function.

I am sure this is something simple, but I missed many hours trying to figure it out.

Below is the code I tried.

The following code works.

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

However, the following code does not work.

 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)") } 

As soon as I move to the next line:

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

I keep getting the following error:

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

Any help with this would be greatly appreciated.

Thanks.

Update

Rintaro noted that testStr should be top, but the following code works.

 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)") } } 

I try not to use global variables unless needed. I may have to, but since I can execute the above code, it seems that I do not need to use a global variable.

+6
source share
1 answer

As discussed in the OP comments, testStr already released.

Is there a way to force save a variable created in a function? Then release it later?

This is not impossible, but I do not know what is the best way to do this.

In any case, try this using the playground or OS X Command Line Tool:

 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) increases the number of deductions.
  • Unmanaged<NSString>.fromOpaque(...).takeRetainedValue() reduces it and retrieves the object.

I think using pure Swift String not possible. because String is a struct and is allocated on the stack. Perhaps its buffer has been allocated to the heap, but we cannot access it directly.

+7
source

Source: https://habr.com/ru/post/977823/


All Articles