2016-02-07 64 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