Ios UIColor子类在从任何?

Ios UIColor子类在从任何?,ios,swift,xcode,uikit,uicolor,Ios,Swift,Xcode,Uikit,Uicolor,我知道,不建议子类化UIColor。苹果说 大多数开发人员不需要将UIColor子类化 但我知道。更多关于为什么可以从我昨天发布的文章中找到。 那个问题已经解决了,但我遇到了另一个问题 假设我有一个自定义颜色类: class MyColor:UIColor{ convenience init(test:String){ self.init(red: 0, green: 0, blue: 0, alpha: 1) } } //Then do this anywhe

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

大多数开发人员不需要将UIColor子类化

但我知道。更多关于为什么可以从我昨天发布的文章中找到。 那个问题已经解决了,但我遇到了另一个问题

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

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..)

myColor
myColor
的一个实例。同一个实例存储在类型为
Any?
的变量中,然后返回到
MyColor
。但它不能

尽管如此,如果我将其转换为
UIColor
一切正常。但我不能在我的情况下这样做(在前面的问题中解释)


为什么这不起作用?

问题是
UIColor
被实现为一个所谓的类集群。这是一种类工厂,但工厂在幕后暗中工作。 在您的示例中,如果您打算创建一个
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]);
在调用initalizer之后,应该获得不同的地址和类

UIColor是一个类群集,它使用类别中的关联引用来 添加属性!UIColor上的所有自定义init方法都返回 UIColor*不是一个id,因此您不能轻松地将UIColor子类化,也不应该这样做 你试试看

您可以遵循以下两条建议:

1-扩展

2-组成


您是否考虑过在
扩展UIColor
中定义便利init而不是子类化
UIColor
是一个“类集群”,这使得子类化非常困难。@MartinR是的,问题是我需要实现一个协议,该协议要求我实现另一个init
init(jsonValue:Apollo.jsonValue)抛出
,在
扩展中实现时,我会遇到几个错误。其中一个是
“required”初始值设定项,必须直接在类“UIColor”中声明(不在扩展名中)
。我不熟悉Apollo,现在没有答案。但是请注意,
print(type(of:myColor))
打印的是“UIDeviceRGBColor”,而不是“myColor”。这是类群集的典型情况,并解释了强制转换失败的原因。@MartinR Apollo与此无关,协议可能只包含init(value:String)抛出。我现在一直在研究类集群,但找不到一种方法来做我需要的事情。你知道有没有一种方法可以控制像这样的东西来得到霉色?我假设集群中的所有子类都是私有的,我不能对任何子类进行子类化,也不能向集群中添加自定义类。一旦您创建了myColor并且退出Apollo,您就不能简单地返回UIColor?
。返回一个不同于您想要创建的实例“
”。如果这是真的,我会觉得有点奇怪,编译器告诉我
let c=MyColor()
MyColor
的实例,而不是
UIColor
。类集群应该有某种特殊的处理或指示来防止这种情况。。因为我写的代码编译得非常完美,没有错误或警告,它只是在运行时崩溃..完全同意;这是Objective C运行时的遗留问题。我不确定您是否可以在Swift中这样做,但您可能会使用Objective C来扩展类集群,遗憾的是,我不能使用扩展(据我所知),因为我需要实现某些协议(在上面的评论和链接的前一个问题中解释)。“作文”就是我现在拥有的。我只是想通过不必使用
myObject.color.color
来使它更性感,但我想这是不可能的:/
extension UIColor {

convenience init(test:String){
    self.init(red: 0, green: 0, blue: 0, alpha: 1)
   }
}

let myColor = UIColor(test: "test")
class MyColor {

private(set) var color: UIColor

init(test:String) {
    color = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
}

}

let myColor = MyColor(test: "test") 
let temp:Any? = myColor 
let c = temp as! MyColor