斯威夫特:非托管 AVAudioPlayer

Posted

技术标签:

【中文标题】斯威夫特:非托管 AVAudioPlayer【英文标题】:Swift: Unmanaged AVAudioPlayer 【发布时间】:2015-07-18 14:20:57 【问题描述】:

我有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")

【问题讨论】:

“创建 nil 实例” - var audioPlayer: Unmanaged&lt;AVAudioPlayer&gt;! - 空 AVAudioPlayer 了解为什么您要“禁用 ARC”会很有趣。这可能是XY problem 吗? var audioPlayer: Unmanaged&lt;AVAudioPlayer&gt;! 声明了一个变量,它不创建任何东西。 这是原始问题:***.com/questions/31212670/… 这就是我需要禁用 ARC 的原因 【参考方案1】:

你应该写:

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

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

现在您可以像往常一样使用self.audioPlayerAVAudioPlayer(或者如果您愿意,也可以使用AVAudioPlayer!,但我不明白为什么)。

self.unmanagedAudioPlayer 保留 self.audioPlayer 的保留引用,这样它就不能被 ARC 释放。

当你处理完这个AVAudioPlayer对象后,你可以调用self.unmanagedAudioPlayer.release()(或autorelease)来释放它,就像你在Objective-C中做的一样。

事实上,您不需要单独存储self.audioPlayer,因为您始终可以通过unmanagedAudioPlayer.takeUnratainedValue() 获取它,但它是一个很好的别名,可以让您的代码更具可读性。

【讨论】:

【参考方案2】:

这是一个没有问题的问题。 “关闭 ARC”的建议是错误的,您不应该尝试这样做。如果你有记忆问题,你应该直接解决它。例如,如果后台的 AVAudioPlayer 出现问题,请在进入后台时将其设置为 nil,以将其从内存中释放。但更重要的是,你应该问自己为什么一开始就有这个问题。我已经使用 AVAudioPlayer 多年了,我从来没有遇到过“它从内存中泄漏”的情况(不管你是什么意思)。

【讨论】:

以上是关于斯威夫特:非托管 AVAudioPlayer的主要内容,如果未能解决你的问题,请参考以下文章

无法调用非函数类型“((AnyObject)-> AnyObject?)!”的值- 斯威夫特 3

斯威夫特,演员:演员隔离属性“扫描”不能从非隔离上下文中变异

无法调用非函数类型“HTTPURLResponse?”的值阿拉莫菲尔 4,斯威夫特 3

将托管类中包含的非托管指针字段传递给非托管代码

在托管代码和非托管代码之间传递非托管结构的安全数组

当应用程序处于非活动状态并运行代码时,Swift iOS 应用程序会收到推送通知