I know, subclassing UIColor
isn't recommended. Apple says
Most developers have no need to subclass 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
This crashes. It crashes because it can't cast temp
to MyColor
:
Could not cast value of type 'UIDeviceRGBColor' (0x..) to 'MyColor' (0x..)
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.
Though, if I cast it to UIColor
everything works. But I can't do that in my case (explained in the previous question).
Why doesn't this work?
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
calls the initializer of the super classMyColor
into something adequate to the parameters, in your case UIDeviceRGBColor
. UIColor.init
does return a different instance than the one you intended to create. This is a subclass of UIColor
, but not of MyColor
any more.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.