CALayer 的子类 VS 类别

Posted

技术标签:

【中文标题】CALayer 的子类 VS 类别【英文标题】:Subclass VS Category for CALayer 【发布时间】:2011-11-24 18:17:47 【问题描述】:

如果我继承 CALayer 并覆盖 drawInContext: 方法,一切都很好。如果我为CALayer 创建一个类别,并在其中覆盖相同的方法(作为子类化的替代方法),它会被调用,但不会绘制任何内容。当然,[super drawInContext:ctx] 在这两种情况下都会被调用。为什么? 我对子类化没有问题,我只是好奇为什么会发生这种情况。我的印象是可以使用类别来添加或覆盖任何类的方法,作为创建整个子类的替代方法。 谢谢!

【问题讨论】:

Selector Sent to method overridden in Category fails的可能重复 基本上,在一个类别中调用超级实现是在您拥有该类别的对象的超类上调用它们,而不是您正在尝试做的原始对象实现。 哦,我明白了,我想我在某处读到,在一个称为原始方法的类别中的一个被覆盖的方法中调用 [super],这听起来很奇怪,但我还是接受了。我错了:) 那么有没有办法做到这一点,调用原始方法? @jrturton:确实,神奇的吓人方法叫"swizzling"。 【参考方案1】:

在一个类别中调用 super 实现会在您拥有该类别的对象的超类上调用它们,而不是在您尝试做的原始对象实现上调用它们。

super,在实例方法中的方法调用上下文中使用时,调用该方法的超类实现。

在一个类别中,您还没有创建子类 - 您编写的代码正在由您拥有该类别的类直接执行。因此,对super 实现的调用将被发送到CALayer 的超类,即NSObject

因此,我有点惊讶您在类别中尝试此操作时没有收到编译器警告。

这里有进一步的精彩讨论:Is calling super in a category the same as calling it in a subclass?

【讨论】:

还应该注意的是,使用类别来覆盖框架类的方法几乎肯定是个坏主意。类的每个实例都使用被覆盖的方法,无论是你创建的还是其他人创建的。

以上是关于CALayer 的子类 VS 类别的主要内容,如果未能解决你的问题,请参考以下文章

如何将 CALayer 子类化为另一个 CALayer 掩码?

自定义 CALayer 子类未显示

使用 Swift3 子类化 CALayer + 隐式动画

在自定义属性更改时重绘自定义 CALayer 子类

UIImageView + UIImage vs CALayer + 内容效率

Swift 中的自定义 UI 元素:子类化 CALayer 并覆盖 drawInContext 导致像素化绘图