2017-07-18 2 views
1

Dans ma classe, j'ai une propriété qui est une sorte de Audioplayer et je prévois de faire le travail d'installation dans une fermeture comme ceci:Problème avec problème d'initialisation de fermeture variables

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

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

    return player }() 

instance membre ' URLPath » ne peut pas être utilisé sur le type 'BackgroundAudio'

enter image description here

Je ne comprends pas tout à fait ce qui est mal avec mon code? Comment résoudre ceci, merci d'avance.

+1

@Rob L'élection du modérateur de cette année à la phase de nomination de débordement de la pile se poursuit et vous souhaite d'y voir en tant que candidat modérateur. –

Répondre

1

Essayez ceci:

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) 
    } 
0

Il y avait une erreur de syntaxe dans votre code. Comme audioPlayer est une propriété calculée, vous ne devriez pas avoir =.

Voici

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

    return player }() 

doit être écrit comme

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

C'est plus agréable, mais cela ne résout pas la racine du problème OP, me semble-t-il. – Rob

0

correcte, il est dit qu'il ne peut pas utiliser l'autre propriété enregistrée lors de l'initialisation, car il ne sait pas si elle est initialisé ou ne pas. Comme The Swift Programming Language dit:

Si vous utilisez une fermeture pour initialiser une propriété, rappelez-vous que le reste de l'instance n'a pas encore été initialisé au point que la fermeture est exécutée. Cela signifie que vous ne pouvez accéder à aucune autre valeur de propriété depuis votre fermeture, même si ces propriétés ont des valeurs par défaut. Vous ne pouvez pas non plus utiliser la propriété implicite self ou appeler l'une des méthodes de l'instance.

Vous pouvez résoudre ce problème en faisant Audioplayer un lazy var, de sorte que l'initialisation est différé jusqu'à ce que vous la première utilisation, la résolution de l'ambiguïté. Par exemple.

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

Ou si vous n'avez pas besoin de cette référence URL ailleurs, vous pouvez simplement avoir une seule constante:

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

Beaucoup d'options. La clé est que vous ne pouvez pas avoir une simple propriété stockée s'initialisant en utilisant la valeur d'une autre propriété. Vous avez besoin de résoudre l'ambiguïté, comme les deux approches ci-dessus.