UIColor-subclass从Any投射时崩溃?

问题描述 投票:2回答:2

我知道,不建议将UIColor子类化。苹果说

大多数开发人员无需继承UIColor

但是我知道。有关更多原因的信息,请参见我昨天发布的another question。该特定问题已解决,但我遇到了另一个问题。

假设我有这个自定义颜色类别:

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,因此崩溃:

无法将类型'UIDeviceRGBColor'(0x ..)的值转换为'MyColor'(0x ..)]

myColorMyColor的实例。相同的实例存储在类型为Any?的变量中,然后强制转换回MyColor。但是不能。

尽管,如果我将其强制转换为UIColor,则一切正常。但是我无法做到这一点(在上一个问题中已有解释)。

为什么不起作用?

ios swift xcode uikit uicolor
2个回答
2
投票

问题在于,UIColor被实现为所谓的class cluster。这是一个类工厂,但是工厂在后台运行。在您的示例中,如果mean创建一个MyColor实例,则内部发生的事情如下:

    MyColor.init调用超类的初始化程序

  • 然后,超类委托给内部类工厂,并将具体实现从MyColor更改为适合参数的情况,在您的情况下为UIDeviceRGBColor
  • 这意味着,UIColor.init返回的实例与您要创建的实例不同。这是UIColor的子类,但不再是MyColor的子类。
  • 在目标C中,您可以更轻松地跟踪此行为:

    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]);

    初始化器被调用后,您应该获得不同的地址和类别。

  • 1
    投票
    UIColor是一个类集群,在一个类别中使用关联引用来添加属性! UIColor上的所有自定义init方法都返回一个UIColor *不是i​​d,因此您不能轻易地继承UIColor,也不应你试试。
    © www.soinside.com 2019 - 2024. All rights reserved.