问题
I have the following Protocol
:
protocol SoundEventDelegate{
func eventStarted(text:String)
}
which I call in this class:
class SoundEvent {
var text:String
var duration:Double
init(text: String, duration: Double){
self.text = text
self.duration = duration
}
var delegate : SoundEventDelegate?
func startEvent(){
delegate?.eventStarted(self.text)
}
func getDuration() -> Double{
return self.duration //TODO is this common practice?
}
}
Which I have my ViewController
conform to:
class ViewController: UIViewController, SoundEventDelegate {
//MARK:Properties
@IBOutlet weak var beginButton: UIButton!
@IBOutlet weak var kleinGrossLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//DELEGATE method
func eventStarted(text:String){
kleinGrossLabel.text = text
}
//MARK: actions
@IBAction func startImprovisation(sender: UIButton) {
var s1:Sentence = Sentence(type: "S3")
var s2:Sentence = Sentence(type: "S1")
var newModel = SentenceMarkov(Ult: s1, Penult: s2)
s1.start()
beginButton.hidden = true
}
}
But when I run the app kleinGrossLabel.text
does not change. Am I referring to the label in the wrong way? Or is it the way that I do delegation that is incorrect?
Here are links to the complete Class
definitions of Sentence
and SentenceMarkov
https://gist.github.com/anonymous/9757d0ff00a4df7a29cb - Sentence
https://gist.github.com/anonymous/91d5d6a59b0c69cba915 - SentenceMarkov
回答1:
First off it's not common practice to have a setter in swift. if you want to have a readonly property you can use private(set) var propertyName
in other cases simply access the property like mentioned in the comment
Also i don't see a reason why you eventArray
in sentence is of type [SoundEvent?]
not [SoundEvent]
as SoundEvent
does not seem to have a failable initialiser
Like mentioned before you need to not only implement the SoundEventDelegate protocol but also set the delegate
the problem is that you can't really access the SoundEventDelegate
from the viewcontroller because you instantiate the SoundEvents
inside Sentence
var soundEventDelegate: SoundEventDelegate?
the easiest way to do this would be adding a soundEventDelegate
property for sentence and setting it like this:
let s1:Sentence = Sentence(type: "S3")
let s2:Sentence = Sentence(type: "S1")
s1.soundEventDelegate = self
s2.soundEventDelegate = self
and inside sound you would need the set the delegate for every event to the soundEventDelegate
of Sentence
you could do it like this:
var soundEventDelegate: SoundEventDelegate? = nil {
didSet {
eventArray.forEach({$0.delegate = soundEventDelegate})
}
}
or write another initialiser that takes the delegate
hope this helps
p.s: you shouldn't inherit form NSObject in swift excepts it's really necessary
回答2:
You never set the delegate property. It's nil. It will never be called.
来源:https://stackoverflow.com/questions/35188922/swift-delegation-protocol-not-setting-uilabel-properly