众所周知,当然,didSet 不会从 didSet 内部再次对同一个对象运行。 ( example .)
但是。似乎:限制不仅适用于该对象,而且可能同一类的任何对象。
这里是 Playground 的复制粘贴测试用例。
class C {
var Test: Bool = false {
didSet {
print("test.")
for c in r {
c.Test = true
}
}
}
var r:[C] = []
}
var a:C = C()
var b:C = C()
var c:C = C()
a.r = [b, c]
a.Test = false
不起作用!
class C {
var Test2: Bool = false {
didSet {
print("test2.")
global.Test2 = true
}
}
}
var global:C = C()
var a:C = C()
a.Test2 = false
不起作用!
这是 Swift 的错误吗?
如果不是,实际限制是什么?它不会运行任何从 didSet 开始的 didSet(无论如何)?同一个类(class)?同一个父类(super class)?或者?
doco 中具体在哪里解释了这一点?
卧槽。人们需要知道……具体的实际限制是什么?
最佳答案
这是错误 SR-419 .
来自对错误的评论:
Ugh. We really need to check that the base of the property access is statically
self.
从我的实验来看,didSet 观察器似乎只有在您为任何对象设置相同的属性时才会被调用。如果您设置任何其他属性(即使在同一个对象上),观察者也会被正确调用。
class A {
var name: String
var related: A?
var property1: Int = 0 {
didSet {
print("\(name), setting property 1: \(property1)")
self.property2 = 100 * property1
related?.property1 = 10 * property1
related?.property2 = 100 * property1
}
}
var property2: Int = 0 {
didSet {
print("\(name), setting property 2: \(property2)")
}
}
init(name: String) {
self.name = name
}
}
let a = A(name: "Base")
a.related = A(name: "Related")
a.property1 = 2
输出:
Base, setting property 1: 2
Base, setting property 2: 200
Related, setting property 2: 200
当预期输出应该是:
Base, setting property 1: 2
Base, setting property 2: 200
Related, setting property 1: 20
Related, setting property 2: 2000
Related, setting property 2: 200
看来您还需要从观察者直接分配该属性。一旦你进入另一个函数(或观察者),观察者又开始工作:
var property1: Int = 0 {
didSet {
print("\(name), setting property 1: \(property1)")
onSet()
}
}
...
func onSet() {
self.property2 = 100 * property1
related?.property1 = 10 * property1
related?.property2 = 100 * property1
}
这是最好的解决方法。
另一种解决方法(感谢 @Hamish)是将嵌套赋值包装到立即执行的闭包中:
var property1: Int = 0 {
didSet {
{
self.property2 = 100 * property1
related?.property1 = 10 * property1
related?.property2 = 100 * property1
}()
}
}
根据闭包前的代码,您可能必须将其括在括号中或在前面的语句后插入分号。
关于swift - 内部didSet保护离奇地延伸到全类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42144752/
在这段Ruby代码中:ModuleMClassC当我尝试运行时出现“'M:Module'的未定义方法'helper'”错误c=M::C.new("world")c.work但直接从另一个类调用M::helper("world")工作正常。类不能调用在定义它们的同一模块中定义的模块函数吗?除了将类移出模块外,还有其他解决方法吗? 最佳答案 为了调用M::helper,你需要将它定义为defself.helper;结束为了进行比较,请查看以下修改后的代码段中的helper和helper2moduleMclassC
我想在Windows7上安装带有ruby1.9.3的rspec-railsgem。我收到一些错误消息,提示无法安装某些json库。所以,我使用下面的说明来解决它。来源=The'json'nativegemrequiresinstalledbuildtools从[rubyinstaller.org][3]下载[Ruby1.9.3][2]从[rubyinstaller.org][3]下载DevKit文件对于Ruby1.9.3,使用[DevKit-tdm-32-4.5.2-20110712-1620-sfx.exe][4]将DevKit解压到路径C:\Ruby193\DevKit运行cd
来自Java,我正在尝试在Ruby中实现LinkedList。我在Java中实现它的通常方法是有一个名为LinkedList的类和一个名为Node的私有(private)内部类,其中LinkedList的每个对象都作为Node对象。classLinkedListprivateclassNodeattr_accessor:val,:nextendend我不想将Node类暴露给外部世界。然而,通过Ruby中的这个设置,我可以使用这个访问LinkedList类之外的私有(private)Node类对象-node=LinkedList::Node.new我知道,在Ruby1.9中,我们可以使用
假设你有这个结构:classHouse请注意,Tv的用户是故意不可访问的。所以你有一个三层嵌套的表单,允许你在一个页面上输入房子、房间和电视。这是Controller的创建方法:defcreate@house=House.new(params[:house])if@house.save#...standardstuffelse#...standardstuffendend问题:您究竟如何为每台电视填充user_id(它应该来自current_user.id)?什么是好的做法?这是我在其中看到的catch22。将user_ids直接填充到params散列中(它们嵌套得很深)保存将失败,因
我已经能够找到:a)用Ruby编写的Lisp解释器(即外部DSL)http://onestepback.org/index.cgi/Tech/Ruby/LispInRuby.redb)作为RubyDSL的Prologhttp://www.kdedevelopers.org/node/2369c)讨论Ruby“作为”一个Lisphttp://www.randomhacks.net/articles/2005/12/03/why-ruby-is-an-acceptable-lisp但奇怪的是,我实际上找不到Lisp的“内部”实现,例如Prolog的实现。我只是不够谷歌,还是还没有人发表过这
我正在使用screen,甚至在rvm1.9.2之后并且有一个合适的.rvmrc我的服务器将仍然使用jruby。我的.screenrc包含shell#{SHELL}rvm信息显示jruby。好像rvm1.9.2没有任何效果,但它在screen外工作正常。 最佳答案 好的,我找到了solution.创建一个.screenrc文件并将此代码段放入其中:shell-$SHELLofficialinstructions省略破折号。 关于ruby-RVMscreen内部损坏,我们在StackOver
我正在将我维护的rubygem从RDoc切换到YARD文档。但是,代码中有一些关键注释只需要保留在代码中,不应出现在文档中。例如:###SomeClassdocumentationhere.#--#CRITICALcommentthatshouldbeinthecodebutnotinthedocumentation,#andmustbeatthisparticularspotinthecode.#++#moredocumentationthatfollowsthecriticalcommentblock,butthispart#shouldbeinthegenerateddocu
这个问题在这里已经有了答案:WhydoRubysettersneed"self."qualificationwithintheclass?(3个答案)关闭7年前。我一直在研究PragmaticProgrammers的“ProgrammingRuby”一书,想知道是否可以在类中调用setter方法,而不是直接分配给实例变量。classBookInStockattr_reader:isbn,:pricedefinitialize(isbn,price)@isbn=isbn@price=Float(price)enddefprice_in_centsInteger(price*100+0.5
我想知道:在Ruby中,有没有一种方法可以在不使用其名称的情况下从自身内部调用方法?如果该方法是通过某些元编程技术创建的,那么通过其名称调用它可能会难以阅读。即使对于通常定义的方法,如果您不确定它的好名字,或者如果它的名字很长,通过一些关键字(类似于super)从自身内部调用它可能会很方便。 最佳答案 您可以使用Kernel#__method__以Symbol形式返回当前方法的名称。与super不同,它不是关键字而是常规方法,因此您必须将它连同必需的参数一起传递给send方法才能调用该方法。这是__method__返回的内容:obj
在一个模块中,我有一个名为Process的类。moduleMProcess=Class.newProcess::wait(0)end这会引发NoMethodError。如何从模块内部访问顶级Process?如果不重命名我的类(class),这完全有可能吗? 最佳答案 ::Process.wait(0) 关于ruby-如何从定义相同名称的模块内部访问ruby中的顶级实体,我们在StackOverflow上找到一个类似的问题: https://stackoverf