鉴于这两个类:
class A: UIView{
var setMe: Int!
@IBInspectable var setMePlease: Int = 0{
didSet{
setMe = setMePlease
}
}
}
class B: A{
@IBInspectable var control: Bool = false{
didSet{
let a = setMe + 1
}
}
}
如果您首先在界面构建器中设置control
和setMePlease
的值,它将会崩溃。为什么didSet会监听插入值的时间而不是类层次结构?有没有办法让值听取层次结构?
答案 0 :(得分:1)
问题是setMe
被定义为隐式展开的可选项,如果在control
的属性观察者中将值分配给setMe
之前设置setMePlease
, setMe
的值将为nil
,导致因展开力而导致崩溃。
如果setMe
值实际上有意义或者提供默认值,则应将nil
声明为简单的可选项。
class A: UIView{
var setMe: Int?
@IBInspectable var setMePlease: Int = 0{
didSet{
setMe = setMePlease
}
}
}
class B: A{
@IBInspectable var control: Bool = false{
didSet{
if let setValue = setMe {
let a = setMe + 1
} else {
let a = 1
}
}
}
}
在初始化期间分配默认值时不会调用属性观察者,因此setMe
从nil
的属性观察者访问时control
为class Parent{
var aCopy:Int?
var a = 1 {
didSet{
aCopy = a
}
}
}
class Child: Parent {
var b = 0{
didSet{
a = 2
let c = (aCopy ?? 0) + b
}
}
}
let child = Child()
child.aCopy //nil
child.a //1
child.b = 1 //b is assigned a new value, so its property observer is called
child.a //2
child.aCopy //2
。
使用以下代码可以很容易地看到这种现象,即属性观察者仅在以编程方式更改变量值后调用,在为其分配默认值时不会调用它:
def invoice
@order = current_user.orders.with_uuid(params[:id])
if @order
@order.order_attachment.with_document_file do |file|
File.open(file.path, 'r') do |f|
send_data f.read, :filename => 'report.pdf',
:type => 'application/pdf',
:disposition => 'attachment'
end
end
else
render nothing: true, status: :not_found
end
end