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

user2517182

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

I am pretty sure it is something simple I am missing but have spent way to many hours trying to figure this out.

Below is some code that I have 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)")
}

Once I get to the following 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 commented that testStr needs to be top level 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 am trying not to use global variables unless I have to. I may have to but since I am able to execute the above code, it seems as though I do not need to use a global variable.

rintaro

As discussed in OP comments, testStr has already been freed.

Is there any way to force the retaining of a variable that has been created in a function? Then release it later?

It's not impossible, but I don't know this is the best way to do that.

Anyway, try this with Playground or OS X "Command Line Tool" template:

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) increments the retain count.
  • Unmanaged<NSString>.fromOpaque(...).takeRetainedValue() decrements it, and extract the object.

I think, using pure Swift String is impossible. because String is struct and is allocated in stack memory. Maybe the buffer of it is allocated in heap, but we cannot access it directly.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Swift UnsafeMutablePointer & UnsafeMutablePointer<UnsafePointer<SomeType>>

Assigning UnsafeMutablePointer value to UnsafePointer without unsafeBitCast

UnsafeMutablePointer<Int8> from String in Swift

How do I get a Swift UnsafePointer from an immutable non-class value?

Swift 2 - UnsafeMutablePointer<Void> to object

Cast a Swift struct to UnsafeMutablePointer<Void>

Swift - converting from UnsafePointer<UInt8> with length to String

How to do pointer arithmetic on UnsafeMutablePointer and get String in Swift 3

Convert UnsafeMutablePointer to UnsafePointer

Cannot convert value of type 'UnsafePointer<UnsafeMutablePointer<Float>>?' to expected argument type 'UnsafePointer<Float>?'

How to cast self to UnsafeMutablePointer<Void> type in swift

Get integer value from string in swift

Using UnsafeMutablePointer and CFRunLoopObserverContext in swift 2

Swift: Cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer'

Get key value from string using Powershell

How to get the value from a string using javascript

get particular value from a string using javascript

Get property value from string using reflection

Get value from JSON string using jQuery

converting ObjC to Swift - UnsafePointer<Void> not convertible to struct type

Cannot assign value of type UnsafeMutablePointer ObjCBool in Swift

Cast a swift dictionary ( [String:AnyObject] ) to a UnsafeMutablePointer

Swift convert string to UnsafeMutablePointer<Int8>

Convert String to UnsafeMutablePointer<char_t> in Swift

Can´t get the SecKey UnsafeMutablePointer in iOS Swift

Swift: Get all key value pairs from a String

Swift, get data from [String: Any] type value

Get return value from void Async Method

How to get value from void method?