初始化 AVAudioPlayer 以在多个函数中使用

Posted

技术标签:

【中文标题】初始化 AVAudioPlayer 以在多个函数中使用【英文标题】:Initializing AVAudioPlayer to be used in more than one function 【发布时间】:2016-11-10 20:14:31 【问题描述】:

通常的AVAudioPlayer 在线教程会在一个函数内创建一个AVAudioPlayer,其中AVAudioPlayer 对象的播放和停止功能不能直接从其他函数中用于该对象。问题是我想要另一个功能来阻止来自AVAudioPlayer 的声音。这看起来很简单,通过初始化类顶部的对象,希望它可以访问,但是在Swift3 中,AVAudioPlayerinit 函数包括throw 和声音文件的参数。 Swift 不允许我们在属性初始化器中使用实例成员,所以我一直在思考如何编写它。

此时我遇到的唯一错误是在创建“backgroundMusicPlayer”时不允许在属性初始化程序中使用实例成员:

import UIKit
import AVFoundation

class MadLibOneViewController: UIViewController, UITextFieldDelegate 

    @IBOutlet weak var thePlace: UITextField!
    @IBOutlet weak var theVerb: UITextField!
    @IBOutlet weak var theNumber: UITextField!
    @IBOutlet weak var theTemplate: UITextView!
    @IBOutlet weak var theStory: UITextView!
    @IBOutlet weak var generateStoryButton: UIButton!
    @IBOutlet weak var proceedToNextMadLib: UIButton!
    //var backgroundMusicPlayer = AVAudioPlayer()

    var error:NSError?

    var path = Bundle.main.path(forResource: "bensound-cute", ofType: "mp3")

    var url: NSURL 
        return NSURL(fileURLWithPath: path!)
    

    var backgroundMusicPlayer: AVAudioPlayer = try AVAudioPlayer(contentsOf: url as URL, error: &error)





    @IBAction func createStory(_ sender: AnyObject) 
        theStory.text=theTemplate.text
    theStory.text=theStory.text.replacingOccurrences(of: "<place>", with: thePlace.text!)
        theStory.text=theStory.text.replacingOccurrences(of: "<verb>", with: theVerb.text!)
        theStory.text=theStory.text.replacingOccurrences(of: "<number>", with: theNumber.text!)

        generateStoryButton.isHidden=true
        proceedToNextMadLib.isHidden=false

    

    @IBAction func showNextStory(_ sender: AnyObject) 

        view.backgroundColor=UIColor.green

        let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
        let resultViewController = storyBoard.instantiateViewController(withIdentifier: "MadLibTwoViewController") as! MadLibTwoViewController
        self.present(resultViewController, animated:true, completion:nil)

    

    @IBAction func hideKeyboard(_ sender: AnyObject) 
        thePlace.resignFirstResponder()
        theVerb.resignFirstResponder()
        theNumber.resignFirstResponder()
        theTemplate.resignFirstResponder()
    
    override func viewDidLoad() 
        super.viewDidLoad()
        proceedToNextMadLib.isHidden=true
        view.backgroundColor = UIColor.purple


        // Do any additional setup after loading the view.
        self.theVerb.delegate = self
        self.thePlace.delegate = self
        self.theNumber.delegate = self

    

    func textFieldShouldReturn(_ textField: UITextField) -> Bool 
        self.view.endEditing(true)
        return false
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    


【问题讨论】:

【参考方案1】:

您需要为此使用Lazy initialisation/instantiation。在你的情况下,这就是你需要做的。

lazy var player: AVAudioPlayer = 
    [unowned self] in
    do 
        return try AVAudioPlayer.init(contentsOf: self.url)
    
    catch 
        return AVAudioPlayer.init()
    

()

有关Lazy Initialisation 的更多信息this 是一本好书。在您的案例中,有趣的是初始化程序throws。我认为this forum discussion 有一个小想法很有帮助。

【讨论】:

编译成功,非常感谢!!我尝试使用惰性但不明白如何使它工作,因为 init 抛出。请问,你在什么情况下使用“有趣”这个词?从我的小经验来看,我相信对于像我这样的菜鸟来说,让事情变得复杂的 init 函数,但是有没有像你这样经验丰富的开发人员更喜欢这个或觉得它“有趣”的原因? @Adeel 哈哈!使用抛出的初始化程序与偏好@user6510422 无关。在这种情况下恰好是这样。这对我来说很有趣,因为它有点挑战性。它归结为态度,而不是新手或经验丰富的人。你一定听过“大师都曾是初学者”的说法。曾经我也是初学者。

以上是关于初始化 AVAudioPlayer 以在多个函数中使用的主要内容,如果未能解决你的问题,请参考以下文章

返回具有多个输入参数的函数的值以在同一类中具有多个参数的另一个函数中使用?

我分配初始化后 AVAudioPlayer 为零

同时使用 AVAudioPlayer 和 MPMoviePlayerController

同步Iphone中两个或多个AVAudioPlayer的播放

如何在播放时在标签中获取 AVAudioplayer 中的当前时间

如何在 AVAudioplayer 中播放多个文件