3

I have AVAudioPlayer instance:

var audioPlayer: AVAudioPlayer!
self!.audioPlayer = AVAudioPlayer(data: fileData, error: &error)
self!.audioPlayer?.numberOfLoops = -1
self!.audioPlayer?.delegate = self

if (self?.audioPlayer?.prepareToPlay() != false) {
    println("Successfully prepared for playing")
} else {
    println("Failed to prepare for playing")
}

I need to disable ARC for this AVAudioPlayer. Unmanaged is not well-documentated, so it is pretty hard to do that. Here's what I've tried:

var audioPlayer: Unmanaged<AVAudioPlayer>!
//Stuck after creating nil instance, what to do now?
self!.audioPlayer = AVAudioPlayer(data: fileData, error: &error)
self!.audioPlayer?.numberOfLoops = -1
self!.audioPlayer?.delegate = self

if (self?.audioPlayer?.prepareToPlay() != false) {
    println("Successfully prepared for playing")
} else {
    println("Failed to prepare for playing")
}
Nikita Zernov
  • 5,465
  • 6
  • 39
  • 70

2 Answers2

2

You should write:

// Properties in your class
var unmanagedAudioPlayer: Unmanaged<AVAudioPlayer>
var audioPlayer : AVAudioPlayer!

// code
self.audioPlayer = AVAudioPlayer(...)
self.unmanagedAudioPlayer = Unmanaged.passRetained(self.audioPlayer)

Now you can use self.audioPlayer as usual as an AVAudioPlayer (or AVAudioPlayer! if you prefer, but I don't see why).

self.unmanagedAudioPlayer keeps a retained reference of self.audioPlayer such that it cannot be deallocated by ARC.

When you are done with this AVAudioPlayer object, you can call self.unmanagedAudioPlayer.release() (or autorelease) to release it as if you are doing the same in Objective-C.

In fact you don't need to store self.audioPlayer separately, because you can always get it via unmanagedAudioPlayer.takeUnratainedValue() but it is a nice alias to make your code more readable.

Alan Tam
  • 2,027
  • 1
  • 20
  • 33
1

This is an un-question. The suggestion to "turn off ARC" is wrong, and you should not be trying to do it. If you have a memory issue you should be tackling it directly. For example, if there's a problem with an AVAudioPlayer in the background, set it to nil as you enter the background, to release it from memory. But even more important, you should be asking yourself why you have this problem to start with. I've been using AVAudioPlayer for years and I've never had a situation where "it leaks from memory" (whatever you mean by that).

matt
  • 515,959
  • 87
  • 875
  • 1,141