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

问题描述

我知道,不推荐子类化 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..)

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

09-22 20:08