变量闭包初始化问题

时间:2017-07-18 05:04:12

标签: ios swift initialization closures

在我的班级中,我有一个属性是一种audioPlayer,我打算在闭包中执行设置工作:

var urlPath = Bundle.main.url(forResource: "Focus", withExtension: "mp3")!

var audioPlayer:AVAudioPlayer = { var player =  try! AVAudioPlayer.init(contentsOf: urlPath)

    return player }()
  

实例成员'urlPath'不能用于'BackgroundAudio'类型

enter image description here

我不太明白我的代码有什么问题?如何解决这个问题,提前谢谢。

3 个答案:

答案 0 :(得分:1)

试试这个:

import AudioToolbox 
 import AVFoundation

let url = Bundle.main.url(forResource: "Focus", withExtension: "mp3")!

    do {
        player = try AVAudioPlayer(contentsOf: url)
        guard let player = player else { return }

        player.prepareToPlay()
        player.play()
    } catch let error as NSError {
        print(error.description)
    }

答案 1 :(得分:0)

您的代码中存在语法错误。由于audioPlayer是计算属性,因此您不应该=

以下

var audioPlayer:AVAudioPlayer = { var player =  try! AVAudioPlayer.init(contentsOf: urlPath)

    return player }()

应该写成

var audioPlayer: AVAudioPlayer {
    var player = try! AVAudioPlayer(contentsOf: urlPath)
    return player
}

答案 2 :(得分:0)

正确,它说它在初始化期间不能使用其他存储属性,因为它不知道它是否已初始化。正如The Swift Programming Language所说:

  

如果使用闭包来初始化属性,请记住在执行闭包时尚未初始化实例的其余部分。这意味着您无法从闭包中访问任何其他属性值,即使这些属性具有默认值也是如此。您也不能使用隐式self属性,也不能调用任何实例的方法。

您可以通过使audioPlayer成为lazy var来解决此问题,因此初始化将推迟到您首次使用它时解决歧义。例如。

var urlPath = Bundle.main.url(forResource: "Focus", withExtension: "mp3")!
lazy var audioPlayer: AVAudioPlayer = try! AVAudioPlayer(contentsOf: self.urlPath)

或者,如果您在其他地方不需要此URL引用,则可以只有一个常量:

let audioPlayer: AVAudioPlayer = {
    var urlPath = Bundle.main.url(forResource: "Focus", withExtension: "mp3")!
    return try! AVAudioPlayer(contentsOf: urlPath)
}()

很多选择。关键是你不能使用另一个属性的值初始化自己的简单存储属性。你需要一些方法来解决歧义,比如上面两种方法。