我有以下类符合协议SentenceDelegate
class SentenceMarkov : SentenceDelegate{
var UltimateSentence : Sentence {
didSet { UltimateSentence.sentenceDelegate = self}
}
var PenultimateSentence : Sentence
init(Ult : Sentence, Penult : Sentence){
self.UltimateSentence = Ult
self.PenultimateSentence = Penult
}
func startChain(){
self.PenultimateSentence.sentenceDelegate = self
self.PenultimateSentence.start()
}
func sentenceDidFinish(){
self.nextSentence(self.UltimateSentence.type, penUltType: self.PenultimateSentence.type)
}
//etc.
}
我将SentenceDelegate
定义如下:
protocol SentenceDelegate: class{
func sentenceDidFinish()
}
最后,我的Delegator类Sentence
定义如下:
class Sentence : NSObject {
var type=""
var eventArray:[SoundEvent] = []
weak var sentenceDelegate: SentenceDelegate?
weak var soundEventDelegate: SoundEventDelegate? = nil {
didSet {
eventArray.forEach() {$0.delegate = soundEventDelegate}
}
}
init(type :String){
//etc.
}
func sentenceDone(){
sentenceDelegate?.sentenceDidFinish() //This is where the program breaks
}
func start(){
self.playEvent(0)
}
func handleTimer(timer: NSTimer) {
guard let index = timer.userInfo as? Int else { return }
playEvent(index)
}
func playEvent(eventIndex : Int){
if (eventIndex < 2){
let currEvent = self.eventArray[eventIndex]
currEvent.startEvent()
let nextIndex = eventIndex + 1
SharingManager.sharedInstance.globalTimer = NSTimer.scheduledTimerWithTimeInterval(currEvent.duration, target: self, selector: Selector("handleTimer:"), userInfo: NSNumber(integer: nextIndex), repeats: false)
}
else if (eventIndex==2){
let currEvent = self.eventArray[eventIndex]
currEvent.startEvent()
SharingManager.sharedInstance.globalTimer = NSTimer.scheduledTimerWithTimeInterval(currEvent.duration, target: self, selector: Selector("sentenceDone"), userInfo: nil, repeats: false)
}
else{
//Nothing
}
}
}
我将上述内容初始化为类,并以下列方式从ViewController
启动程序:
let s1:Sentence = Sentence(type: "S3")
let s2:Sentence = Sentence(type: "S1")
var newModel = SentenceMarkov(Ult: s1, Penult: s2)
newModel.startChain()
当我运行程序时,它不会在Delegate类上执行SentenceDelegate
方法sentenceDidFinish
。当我为该方法设置断点时,程序永远不会停止。当我在Delegator类的sentenceDone
上设置断点时,我检查self
变量,看到sentenceDelegate
已定义,但指向Delegator类的两个副本({{1} }和UltimateSentence
)而不是Delegate类。此外,在使用断点检查时,Delegator类的这两个实例具有PenultimateSentence
属性sentenceDelegate
。
与照片商量:
我不明白nil
属性Sentence
(他在 SentenceMarkov 中设置为sentenceDelegate
)如何指向一个句子,而不是如何调用self
{1}}。任何阐明我在推理/编程中的错误都将非常感激。
答案 0 :(得分:1)
问题是您将didSet
与init
结合使用。在init
期间不会调用这些方法,因此您需要创建一个特定的方法,并在init
内调用它。例如;
var UltimateSentence : Sentence {
didSet { setDelegate() }
}
func setDelegate() {
UltimateSentence.sentenceDelegate = self
}
init(Ult : Sentence, Penult : Sentence){
self.UltimateSentence = Ult
self.PenultimateSentence = Penult
setDelegate()
}
您也只是对代表保持弱引用。我不清楚有什么强烈的参考。如果没有任何强大的参考,它们将在超出范围时被销毁。您可以通过在print
deinit
内加SentenceMarkov
来确认这一点。
值得注意的是,Swift标准适用于以大写字母开头的类和以小写字母开头的实例。当你的实例以大写字母开头时,它使得习惯这个惯例的人更难阅读。