Swift 4.1 - 继承 UIImage

7
升级到 Swift 4.1 后,使用自定义初始化程序子类化 UIImage 时,会出现“不支持从扩展覆盖非 @objc 声明”的错误。
class Foo: UIImage {

    init(bar: String) { }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // Overriding non-@objc declarations from extensions is not supported
    required convenience init(imageLiteralResourceName name: String) {
        fatalError("init(imageLiteralResourceName:) has not been implemented")
    }
}

感谢您的帮助。

UIImage 不适合子类化。请尝试使用组合而非继承。 - Tony Macaren
2个回答

5
extension UIImage {

    /// Creates an instance initialized with the given resource name.
    ///
    /// Do not call this initializer directly. Instead, initialize a variable or
    /// constant using an image literal.
    required public convenience init(imageLiteralResourceName name: String)
}

这个init方法是在UIImage类的扩展中声明的。

这个错误基本上是说,如果一个函数是在扩展中声明的,那么它不能以这种方式被重写。

class Foo: UIImage {

}

extension Foo {
    convenience init(bar :String) {
        self.init()
    }
}

var temp = Foo(bar: "Hello")

您可以尝试以此方式实现所需结果。

它不起作用。 - Tony Macaren

2

问题似乎是由于init(bar:)这个指定初始化方法导致的,如果你将它转换成一个便利初始化方法,那么这个类就可以编译通过:


class Foo: UIImage {

    convenience init(bar: String) { super.init() }

    // no longer need to override the required initializers
}

似乎一旦添加了指定的初始化程序(即非便利初始化程序),Swift 将强制执行从基类覆盖所有必需的初始化程序。 对于UIImage,我们有一个存在于扩展中的初始化程序(不确定它是如何到达那里的,可能是自动生成的,因为我自己无法在扩展中添加所需的初始化程序)。 这就是讨论中遇到编译器错误的原因。
最初的回答:似乎一旦使用指定的初始化程序(非便捷初始化程序),Swift 会强制要求从基类覆盖所有必需的初始化程序。对于UIImage,我们在扩展中有一个初始化程序(可能是自动生成的),我无法在扩展中添加一个所需的初始化程序,因此会遇到编译器错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接