我有以下符合协议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类的两个副本(UltimateSentencePenultimateSentence),并且不是委托类。此外,在使用断点检查时,Delegator类的这两个实例具有sentenceDelegate属性,这些属性均为nil

授予照片:

ios - Delgator的委托(delegate)属性指向两个Delegators,而不是Delegate类-LMLPHP

ios - Delgator的委托(delegate)属性指向两个Delegators,而不是Delegate类-LMLPHP
我不明白Sentence属性sentenceDelegate(他在SentenceMarkov中将其设置为self)如何指向一个句子,而不是指向sentenceDidFinish的Delegate类。对我在推理/编程中的错误的任何阐明将不胜感激。

最佳答案

问题是您将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()
}


您也只是对代表保持弱引用。我不清楚什么对他们有很强的参考意义。如果没有什么东西有很强的参考意义,那么一旦超出范围,它们将被销毁。您可以通过在printdeinit内放置SentenceMarkov来确认这一点。
值得注意的是,Swift标准是针对类以大写字母开头,而实例以小写字母开头。当您的实例以大写字母开头时,对于习惯该约定的人来说,阅读起来会更加困难。

关于ios - Delgator的委托(delegate)属性指向两个Delegators,而不是Delegate类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35260342/

10-10 08:41