(我在标题中说“更多”,因为这个问题是我的How does Swift ReferenceWritableKeyPath work with an Optional property? 的附录?。)
在我的代码中,self.iv
是一个插座属性:
@IBOutlet weak var iv: UIImageView!
现在,这会编译吗?
let im = UIImage()
let kp = \UIImageView.image
self.iv[keyPath:kp] = im // error
不!我们被告知这里的某些东西必须打开,尽管它是什么并不完全清楚:
可选类型“UIImage?”的值 必须解包为“UIImage”类型的值
但现在看这个。我将只制作一个图像视图,而不是一个插座:
let im = UIImage()
let kp = \UIImageView.image
let iv = UIImageView()
iv[keyPath:kp] = im
编译!为什么?UIImageView 属性和 UIImageView 本地之间有什么语义/句法区别?是否该属性是隐式展开的 Optional?
为了测试这个想法,让我们通过本地“传播”self.iv
显式展开:
let im = UIImage()
let kp = \UIImageView.image
let iv = self.iv!
iv[keyPath:kp] = im
那也编译!但是我们必须使用单独的本地;仅仅self.iv
直接展开是不够的:
let im = UIImage()
let kp = \UIImageView.image
self.iv![keyPath:kp] = im // error
我根本不明白这一点。它违背了我关于隐式展开的 Optional 是什么以及如何始终将非 Optional 分配给包装相同类型的 Optional 的标准信念。关于 ReferenceWritableKeyPath 的一些东西似乎与 Optional 属性一起工作很奇怪,但我不能把手指放在它上面。
所以我的问题是(抱歉,可能有点含糊):有人可以证明所有这些结果的合理性,并使它们看起来合理且可预测吗?这里有什么规则?