为什么在 wantsLayer=true 之后 layer 会是 nil?

Why would layer be nil, after wantsLayer=true?

我在 Xcode 8 中新建了一个 OS X 项目,添加了单个(图像)视图。我将它拖到默认的 ViewController 源,以添加一个 @IBOutlet(名为 "image")。然后在 viewDidLoad() 中,我添加了:

image.wantsLayer = true
image.layer!.cornerRadius = 10

大约一半的时间,它工作正常,大约一半的时间,它死于:

fatal error: unexpectedly found nil while unwrapping an Optional value

同时指向第二行,并在调试器中:

(lldb) po image.wantsLayer
true

(lldb) po image.layer
nil

设置 wantsLayer 是否应该立即创建 layer?文档似乎暗示了这一点,但我找不到明确说明这一点的声明。

我看过很多代码,like this,它让 NSView 做:

self.wantsLayer = true
self.layer!.backgroundColor = ...

所以看起来应该如此。为什么设置wantsLayerlayer为nil?我是否应该自己设置 layer,即使我要求设置 wantsLayer

对于 OS X 上的图层支持视图,不建议直接与图层对象交互。该层归 AppKit 所有。此处也用几句话描述了这一点:https://www.objc.io/issues/14-mac/appkit-for-uikit-developers/

现在,如果您在 NSViewwantsUpdateLayer 属性 上子类化您的视图和 return YES/true,您可以更新 updateLayer。请注意,这将导致 AppKit 不再调用 drawRect

对于未来的搜索者,这里的 Swift 3 代码可以安全地设置图像(或 NSView)的角半径,不需要子类化。直接访问该层是危险的,因为 NSViews 并不总是由 Core Animation 层支持。相反,您可以创建一个图层托管视图并写入该视图。

因此,在 viewDidLoad():

let layer = CALayer()
image.layer = layer
image.wantsLayer = true
image.masksToBounds = true
image.cornerRadius = 19