
class TwiceInt { var value:Int = 0 { dIDSet { value *= 2 } }}class QuadInt : TwiceInt { overrIDe var value:Int { dIDSet { value *= 4 } }}let t = TwiceInt()t.value = 5 // this works finelet q = QuadInt()q.value = 5 // this ends up in recursion 如果我更新QuadInt
class QuadInt : TwiceInt { overrIDe var value:Int { dIDSet { super.value *= 4 } }}q.value = 5 // q.value = 80 所以我猜这个电话是这样的:
value = 5QuadInt:dIDSet ( value *= 4 )value = 20TwiceInt:dIDSet ( value *= 2 )value = 40TwiceInt:dIDSet ( value *= 2 )value = 80
这或多或少是在黑暗中拍摄.有没有关于物业更新会发生什么的文件?
你不能覆盖dIDSet,这不是一个普通的方法.实际上你没有覆盖dIDSet,你自己覆盖了属性.dIDSet的作品像观察者一样工作,只是因为你将自己的观察者设置在一个继承的属性上,并不意味着任何其他观察者自动被注册.所以你的超类的观察者完全不受这个影响,因此这两个dIDSet方法都将被调用到最后.
现在,如果您在自己的dIDSet观察器中更改值,则不会导致递归,因为Swift运行时足够聪明,以了解在执行此 *** 作后,doSet实现将更改其自己的观察属性不会被再次调用.运行时知道当前正在执行的是什么dIDSet方法,如果变量在此方法返回之前更改,则不会再执行该方法.这个检查似乎不能跨越超类.
所以* = 4导致调用超类观察器,它设置* = 2,并且导致再次调用子类观察器,这将再次设置* = 4,导致再次调用超类观察者…和等等.
通过明确使用超级,你打破了这个循环,因为现在你没有设置你的被覆盖的属性,而是继承的超级属性,你并没有真正观察超级属性,你只是观察自己的覆盖的属性.
在一些语言中,您可以遇到与覆盖方法类似的问题,其中典型的解决方案也是在其中一个调用中显式地使用super.
总结以上是内存溢出为你收集整理的Swift:覆盖didSet会导致递归全部内容,希望文章能够帮你解决Swift:覆盖didSet会导致递归所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)