代码之家  ›  专栏  ›  技术社区  ›  Nikita Zernov

Swift:非托管AVAudioPlayer

  •  3
  • Nikita Zernov  · 技术社区  · 9 年前

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

    我需要为此禁用ARC AVAudioPlayer(音频播放器) . 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")
    }
    
    2 回复  |  直到 9 年前
        1
  •  2
  •   Alan Tam    9 年前

    你应该写:

    // 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 保留的引用 自拍播放器 使得它不能被ARC解除分配。

    当你做完这个 AVAudioPlayer(音频播放器) 对象,您可以调用 self.unmanagedAudioPlayer.release() (或 autorelease )就像在Objective-C中一样发布它。

    事实上,您不需要存储 自拍播放器 分开,因为你总是可以通过 unmanagedAudioPlayer.takeUnratainedValue() 但它是一个很好的别名,可以使代码更可读。

        2
  •  1
  •   matt    9 年前

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