问题描述
我知道,不推荐子类化 UIColor
.苹果说
I know, subclassing UIColor
isn't recommended. Apple says
大多数开发者不需要继承 UIColor
但我愿意.更多关于为什么可以从我昨天发布的另一个问题中找到.那个特定问题已解决,但我遇到了另一个问题.
But I do. More on why can be found from another question I posted yesterday.That particular issue was solved, but I met another problem.
假设我有这个自定义颜色类:
Let's say I have this custom color class:
class MyColor:UIColor{
convenience init(test:String){
self.init(red: 0, green: 0, blue: 0, alpha: 1)
}
}
//Then do this anywhere:
let myColor = MyColor(test: "test")
let temp:Any? = myColor
let c = temp as! MyColor
这会崩溃.它崩溃是因为它无法将 temp
转换为 MyColor
:
This crashes. It crashes because it can't cast temp
to MyColor
:
无法将 'UIDeviceRGBColor' (0x..) 类型的值转换为 'MyColor' (0x..)
myColor
是 MyColor
的一个实例.同样的实例存储在 Any?
类型的变量中,然后转换回 MyColor
.但它不能.
myColor
is an instance of MyColor
. This same instance is stored in a variable of type Any?
, and then cast back to MyColor
. But it can't.
不过,如果我将它转换为 UIColor
一切正常.但在我的情况下我不能这样做(在上一个问题中解释).
Though, if I cast it to UIColor
everything works. But I can't do that in my case (explained in the previous question).
为什么这不起作用?
推荐答案
问题在于 UIColor
被实现为所谓的类簇.这是一种类工厂,但工厂在幕后隐式工作.在您的示例中,如果您意思创建一个 MyColor
实例,则内部发生的情况如下:
The problem is that UIColor
is implemented as a so-called class cluster. It's a kind of class factory, but the factory is working implicitly under the hood.In your example, if you mean to create a MyColor
instance, what happens internally is the following:
MyColor.init
调用超类的初始化器- 超类然后委托给内部类工厂并将具体实现从
MyColor
更改为适合参数的内容,在您的情况下为UIDeviceRGBColor
. - 这意味着,
UIColor.init
确实返回了与您打算创建的实例不同的实例.这是UIColor
的子类,但不再是MyColor
的子类.
MyColor.init
calls the initializer of the super class- The super class then delegates to a internal class factory and changes the concrete implementation from
MyColor
into something adequate to the parameters, in your caseUIDeviceRGBColor
. - This means,
UIColor.init
does return a different instance than the one you intended to create. This is a subclass ofUIColor
, but not ofMyColor
any more.
在目标 C 中,您可以更轻松地跟踪此行为:
In Objective C, you can trace this behaviour more easily:
UIColor *color = [UIColor alloc];
NSLog(@"Address after alloc: %p - class: %@", color, [color class]);
color = [color initWithRed:1.0, green:1.0, blue:1.0, alpha:1.0];
NSLog(@"Address after init: %p - class: %@", color, [color class]);
在调用初始化程序后,您应该获得不同的地址和类.
You should get a different address and class after the initalizer has been called.
这篇关于从 Any 投射时 UIColor 子类崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!