Delgator的委托属性指向两个Delegator而不是Delegate类

时间:2016-02-07 23:10:29

标签: ios swift delegates

我有以下类符合协议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

与照片商量:

enter image description here

enter image description here 我不明白nil属性Sentence(他在 SentenceMarkov 中设置为sentenceDelegate)如何指向一个句子,而不是如何调用self {1}}。任何阐明我在推理/编程中的错误都将非常感激。

1 个答案:

答案 0 :(得分: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内加SentenceMarkov来确认这一点。 值得注意的是,Swift标准适用于以大写字母开头的类和以小写字母开头的实例。当你的实例以大写字母开头时,它使得习惯这个惯例的人更难阅读。