Swift 中的子类不继承其超类的初始化程序

Subclass in Swift does not inherit initialiser of its superclass

我在尝试继承 NSBezierPath 时偶然发现了一个非常奇怪的问题。

下面是我的子类的定义:

class OSBezierPath: NSBezierPath {
        
    func addLineToPoint(point:CGPoint) {
        self.lineToPoint(point)
    }
}

除了我无法访问 NSBezierPath 的某些初始化程序这一事实外,该子类还可以工作。例如,下面的行是无效的:

let path = OSBezierPath(ovalInRect: rect)

编译器抛出错误

Extra argument 'ovalInRect' in call

此错误的原因

这个错误的原因在 中有很好的解释。但是,建议的答案对我来说效果不佳,因为我想要实现的是在 iOS 和 Mac OS.[=19= 上使用 OSBezierPath ]

我原来的代码是这样写的:

#if os(iOS)
    typealias OSBezierPath = UIBezierPath
#else
    class OSBezierPath: NSBezierPath {
        
        func addLineToPoint(point:CGPoint) {
            self.lineToPoint(point)
        }
    }
#endif

此代码不起作用,但我发现了 2 个解决方法,它们比另一个问题中的建议答案更适合我的目的。

第一个解决方案

此解决方案使用扩展来向 NSBezierPath 添加一个函数,这将允许它以与 UIBezierPath.

相同的方式绘制线条
#if os(iOS)
    typealias OSBezierPath = UIBezierPath
#else
    typealias OSBezierPath = NSBezierPath
    
    extension OSBezierPath {
        func addLineToPoint(point:CGPoint) {
            self.lineToPoint(point)
        }
    }
#endif

这避免了任何潜在的错误,因为不涉及子classing。因此,下面一行:

let path = OSBezierPath(ovalInRect: rect)

实际翻译为:

let path = NSBezierPath(ovalInRect: rect)

所以编译器很高兴 :)

第二个解决方案(Xcode 7)

第二种解决方案使用 UIBezierPath 的 class 函数在 Xcode 7 中转换为适当的初始化器这一事实。因此,下面的代码将起作用:

#if os(iOS)
    class OSBezierPath: UIBezierPath {
        func lineToPoint(point:CGPoint) {
            self.addLineToPoint(point)
        }
    }
#else
    typealias OSBezierPath = NSBezierPath
#endif

这允许我们通过在 iOS 和 Mac OS.

上调用 lineToPoint 来使用 OSBezierPath