Delgator的委托属性指向两个Delegator而不是Delegate类(Delgator's delegate property points to two Delegators an

编程入门 行业动态 更新时间:2024-10-28 16:28:55
Delgator的委托属性指向两个Delegator而不是Delegate类(Delgator's delegate property points to two Delegators and not to the Delegate class)

我有以下类符合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类( UltimateSentence和PenultimateSentence )的两个副本,而不是Delegate类。 此外,在使用断点检查时,Delegator类的这两个实例的sentenceDelegate属性为nil 。

与照片商量:

我不明白Sentence属性sentenceDelegate (他在SentenceMarkov中设置为self )指向一个句子而不是一个调用sentenceDidFinish的Delegate类。 任何阐明我在推理/编程中的错误都将非常感激。

I have the following class which conforms to a protocol 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. }

I define the SentenceDelegate as follows:

protocol SentenceDelegate: class{ func sentenceDidFinish() }

Finally, my Delegator class, Sentence is defined as follows:

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

I initialize the above to class and start the program from my ViewController in the following fashion:

let s1:Sentence = Sentence(type: "S3") let s2:Sentence = Sentence(type: "S1") var newModel = SentenceMarkov(Ult: s1, Penult: s2) newModel.startChain()

When I run the program it does not execute the SentenceDelegate method sentenceDidFinish on the Delegate class. When I set a break point to that method, the program never stops. When I set a breakpoint on sentenceDone in the Delegator class, I inspect the self variable, and see that sentenceDelegate is defined, but points to two copies of the Delegator class (UltimateSentence and PenultimateSentence) and not the Delegate class. Furthermore, that these two instances of the Delegator class, upon using the breakpoint inspection, have sentenceDelegate properties which are nil.

Confer with photos:

I don't understand how the Sentence property sentenceDelegate (which his set to self in SentenceMarkov ) points to a sentence and not the Delegate class which calls sentenceDidFinish. Any elucidation of my errors in reasoning / programming would be greatly appreciated.

最满意答案

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

您也只是对代表保持弱引用。 我不清楚它们对它们的强烈提及。 如果没有任何强大的参考,它们将在超出范围时被销毁。 您可以通过在SentenceMarkov的deinit中放置一个print来确认这一点。 值得注意的是,Swift标准用于以大写字母开头的类和以小写字母开头的实例。 当你的实例以大写字母开头时,它使得习惯这个约定的人更难阅读。

The problem is that you are using didSet in conjunction with init. These methods are not called during init, so you would need to create a specific method and call that within the init as well. For example;

var UltimateSentence : Sentence { didSet { setDelegate() } } func setDelegate() { UltimateSentence.sentenceDelegate = self } init(Ult : Sentence, Penult : Sentence){ self.UltimateSentence = Ult self.PenultimateSentence = Penult setDelegate() }

You are also only keeping a weak reference to the delegates. It's not clear to me what has a strong reference to them. If nothing has a strong reference they will be destroyed once out of scope. You could confirm this by putting a print inside the deinit of SentenceMarkov. It's also worth noting that the Swift standard is for classes to start with an uppercase letter and instances to start with lower case. It makes it harder to read for people used to this convention, when your instances start with upper case.

更多推荐

本文发布于:2023-07-31 07:12:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1341863.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:而不是   属性   两个   Delgator   Delegator

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!