Swift:非托管 AVAudioPlayer
Swift: Unmanaged AVAudioPlayer
我有 AVAudioPlayer
个实例:
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")
}
我需要为此 AVAudioPlayer
禁用 ARC。 Unmanaged
没有很好的文档记录,所以很难做到这一点。这是我尝试过的:
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")
}
你应该写:
// Properties in your class
var unmanagedAudioPlayer: Unmanaged<AVAudioPlayer>
var audioPlayer : AVAudioPlayer!
// code
self.audioPlayer = AVAudioPlayer(...)
self.unmanagedAudioPlayer = Unmanaged.passRetained(self.audioPlayer)
现在您可以像往常一样使用 self.audioPlayer
作为 AVAudioPlayer
(如果您愿意,也可以使用 AVAudioPlayer!
,但我不明白为什么)。
self.unmanagedAudioPlayer
保留对 self.audioPlayer
的保留引用,这样它就不能被 ARC 释放。
当你用完这个AVAudioPlayer
对象后,你可以调用self.unmanagedAudioPlayer.release()
(或autorelease
)来释放它,就像你在Objective-C中做的一样.
实际上您不需要单独存储 self.audioPlayer
,因为您始终可以通过 unmanagedAudioPlayer.takeUnratainedValue()
获取它,但它是使您的代码更具可读性的好别名。
这不是问题。 "turn off ARC" 的建议是错误的,您不应该尝试这样做。如果你有内存问题,你应该直接解决它。例如,如果后台的 AVAudioPlayer 有问题,请在进入后台时将其设置为 nil
,以将其从内存中释放。但更重要的是,您应该问自己为什么会遇到这个问题。多年来我一直在使用 AVAudioPlayer,我从来没有遇到过 "it leaks from memory"(不管你是什么意思)的情况。
我有 AVAudioPlayer
个实例:
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")
}
我需要为此 AVAudioPlayer
禁用 ARC。 Unmanaged
没有很好的文档记录,所以很难做到这一点。这是我尝试过的:
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")
}
你应该写:
// Properties in your class
var unmanagedAudioPlayer: Unmanaged<AVAudioPlayer>
var audioPlayer : AVAudioPlayer!
// code
self.audioPlayer = AVAudioPlayer(...)
self.unmanagedAudioPlayer = Unmanaged.passRetained(self.audioPlayer)
现在您可以像往常一样使用 self.audioPlayer
作为 AVAudioPlayer
(如果您愿意,也可以使用 AVAudioPlayer!
,但我不明白为什么)。
self.unmanagedAudioPlayer
保留对 self.audioPlayer
的保留引用,这样它就不能被 ARC 释放。
当你用完这个AVAudioPlayer
对象后,你可以调用self.unmanagedAudioPlayer.release()
(或autorelease
)来释放它,就像你在Objective-C中做的一样.
实际上您不需要单独存储 self.audioPlayer
,因为您始终可以通过 unmanagedAudioPlayer.takeUnratainedValue()
获取它,但它是使您的代码更具可读性的好别名。
这不是问题。 "turn off ARC" 的建议是错误的,您不应该尝试这样做。如果你有内存问题,你应该直接解决它。例如,如果后台的 AVAudioPlayer 有问题,请在进入后台时将其设置为 nil
,以将其从内存中释放。但更重要的是,您应该问自己为什么会遇到这个问题。多年来我一直在使用 AVAudioPlayer,我从来没有遇到过 "it leaks from memory"(不管你是什么意思)的情况。