CALayerDelegate displayLayer 和 NSView updateLayer 有什么区别

What's the difference between CALayerDelegate displayLayer and NSView updateLayer

[CALayerDelegate displayLayer:]描述为here

[NSView updateLayer]描述为here

它们有什么不同?我什么时候会用一个而不是另一个?

-[NSView updateLayer:]

此方法的目的是被 NSView 子类覆盖,以便您可以自定义支持层。默认情况下,将使用 -[NSView drawRect:] 并且您不应该直接操作支持层(就像您可能在 iOS 上使用 UIView 一样)。如果你想自定义底层,你应该使用 -updateLayer 并在这个方法中执行你的自定义。要选择使用 updateLayer 而不是 drawRect:,您需要覆盖 -[NSView wantsUpdateLayer] 和 return YES。现在,您可以更改 -updateLayer 内衬层上的任何 属性。要通知视图需要发生更改,您可以使用 needsDisplay 属性 并将其设置为 YES,这将在执行渲染过程时触发 -updateLayer。了解控制何时触发重绘的 layerContentsRedrawPolicy 属性 也很好。

用法示例:

@implementation MyView

- (BOOL)wantsUpdateLayer {
    return YES;
}

- (void)updateLayer {
    // Perform different customizations based on view/control state.
    self.layer.backgroundColor = NSColor.redColor.CGColor;
    self.layer.contents = <some image>;
}

@end

// Example of notifying MyView instance that it needs to update itself
myView.needsDisplay = YES;

一个video的无耻插件,我最近在这个话题上做了一些。

-[CALayerDelegate displayLayer:]

此调用特定于 CALayer。如果您不处理 NSView,那么这就是您可以通过调用 -[CALayer setNeedsDisplay].

通知 CALayer 需要更改的方式

简而言之,如果您正在处理 NSView 并希望完全控制支持层,则必须将 -wantsUpdateLayer 覆盖为 return YES 并且实施 -updateLayer。如果您直接使用 CALayers(不涉及 NSView),那么代理在这里很有用。

这是我自己的发现。

如果覆盖 -[NSView makeBackingLayer],则 必须 使用 -[CALayerDelegate displayLayer:] 而不是 -[NSView updateLayer]


CALayer 与 NSViewBackingLayer

如果您不覆盖 makeBackingLayer 并将 wantsLayer 设置为 YES,则默认层 class 称为 _NSViewBackingLayer

它在以下方面与 CALayer 的行为不同:

  • 占用内存明显减少。
  • 在设置 transform 属性 时调用 setNeedsDisplay:YES
  • 也许还有其他方式...?