2016-02-07 70 views
0

我有以下的類,它遵循的協議SentenceDelegateDelgator的委託財產分兩個委託者,而不是Delegate類

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

最後,我的委託人類別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() 

當我運行它,它不會對委託類執行SentenceDelegate方法sentenceDidFinish。當我爲該方法設置一箇中斷點時,程序不會停止。當我在Delegator類中的sentenceDone上設置斷點時,我檢查self變量,並看到sentenceDelegate已定義,但指向Delegator類的兩個副本(UltimateSentencePenultimateSentence),而不是Delegate類。此外,Delegator類的這兩個實例在使用斷點檢查時具有sentenceDelegate屬性nil

賦予與照片:

enter image description here

enter image description here 我不明白是怎麼Sentence財產sentenceDelegate(其中他的一套以selfSentenceMarkov)指向一個句子,而不是委託類請致電sentenceDidFinish。任何澄清我的推理/編程錯誤將不勝感激。

回答

1

問題是,您正在使用didSetinit一起使用。在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內來確認。 另外值得一提的是,Swift標準是以大寫字母開頭的類和以小寫字母開頭的實例。當你的實例以大寫字母開頭時,它使得習慣於這種約定的人難以閱讀。

+0

問題,如果我還需要設置'penultimateSentence'的委託,該怎麼辦。我應該創建另一種特定的方法嗎? – Thalatta

+0

並且像你一樣調用'init()'? – Thalatta

+1

是的,絕對是從'init'打電話給他們的。 – Michael