从 Any 投射时 UIColor 子类崩溃? [英] UIColor-subclass crashes when casting from Any?

查看:23
本文介绍了从 Any 投射时 UIColor 子类崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,不推荐子类化 UIColor.苹果说

I know, subclassing UIColor isn't recommended. Apple says

大多数开发者不需要继承 UIColor

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

这会崩溃.它崩溃是因为它无法将 temp 转换为 MyColor:

This crashes. It crashes because it can't cast temp to MyColor:

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

Could not cast value of type 'UIDeviceRGBColor' (0x..) to 'MyColor' (0x..)

myColorMyColor 的一个实例.同样的实例存储在 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 case UIDeviceRGBColor.
  • This means, 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.

在目标 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 子类崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆