【问题标题】:Why overriding UIView.drawRect makes "calling -display has no effect" message to appear?为什么覆盖 UIView.drawRect 会出现“调用 -display 无效”消息?
【发布时间】:2015-03-27 11:57:08
【问题描述】:

注意:我不寻求解决实际问题。我出于好奇而问。

我有一个自定义的UIView 子类,我在应用程序的主视图中使用它。它有一个金属层类:

+ (id)layerClass
{
    return [CAMetalLayer class];
}

我注意到如果我重写-(void)drawRect:(CGRect)rect 方法,就会开始出现错误消息:

<CAMetalLayer: 0x17005dc70>: calling -display has no effect.

更有趣的是,即使我这样覆盖它也会出现:

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
}

据我了解,这根本不可能产生任何影响,因为根据 OOP 的基本原则,这样的覆盖(仅调用基类)不应该修改程序的行为。

此错误消息究竟意味着什么?为什么会出现?

【问题讨论】:

  • 也许是因为你的 CAMetalLayer 没有像默认的 CALayer 那样将你的 UIView 设置为它的委托,它只是让你知道你在 drawRect 中浪费你的时间:因为它不会被调用...
  • @Jef 不,对于作为UIView 支持层的层更改委托是非法的。但是,覆盖 drawRect 实际上会有所不同。他们的系统实际上检查该方法是否被覆盖。
  • 能否再添加一些与图层相关的代码?该警告的最初原因可能是不同的行。

标签: ios objective-c uiview metal


【解决方案1】:

UIView API ,它不是一个好的 API。 UIViewCALayer 之间的交互相当复杂。有趣的是系统会检查您是否覆盖drawRect。这就是UIView 文档中出现此警告的原因:

drawRect: - 如果您的视图绘制自定义内容,请实施此方法。如果您的视图不进行任何自定义绘图,请避免覆盖此方法。

无需致电[super drawRect:rect]。超类不进行实际绘图。如果您不想绘制任何东西,请完全删除该方法。如果您想在图层上绘制自定义内容,请不要调用 super(只有在您知道超类也已覆盖 drawRect 时才调用 super)。

如果你直接继承 UIView,你的这个方法的实现不需要调用 super.但是,如果您要对不同的视图类进行子类化,则应在实现中的某个时刻调用 super。

在你的情况下,我相信调用 [super drawRect] 做了一些不应该发生的事情。

【讨论】:

  • "系统检查你是否覆盖 drawRect。"这怎么可能?为什么会这样写?
  • “在你的情况下,我相信调用 [super drawRect] 做了一些不应该发生的事情。”这不是真的,因为无论我是否调用 super,我都会得到完全相同的结果。
  • @golergka 这是可能的,因为 obj-c 是一种非常动态的语言,具有强大的反射能力。可以在这里看到一种方法:stackoverflow.com/questions/28737116/…。最初的原因可能与性能有关。大多数图层都被缓存并且不会每次都重绘。将自定义代码添加到方程式后,系统优化重绘的能力就会下降。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多