我正在设计一个使用协议和扩展的框架,以允许第三方将我的框架支持添加到现有的类中。
我还想为UIView等已知类添加一些内置扩展,但我不想阻止用户为相同的类定义自己的附加支持。
我的问题是,有没有什么方法可以将同一个类扩展两次,并且在该类中同时覆盖相同的(协议)方法,同时如果第一个失败则还有一些方法可以调用另一个。
详细说明:我想在这里实现三个目标:
我已经完成了第1部分工作。问题是如何实现这种回退行为。如果我使用扩展来完成所有操作,子类将覆盖超类的协议方法的实现。它可以调用super.method
,但我想避免将该责任放在子类上(如果作者忘记调用super
)。
我想从框架代码中完成所有这些:首先,调用对象的协议方法。如果它返回false,我想以某种方式调用泛型UIView处理程序。
现在我正在打字,我想知道我是否可以使用不同的方法进行通用回退并完成它。我只是觉得如果我能用一种方法做到这一点会很优雅。
答案 0 :(得分:3)
没有!它不能多次扩展。
extension Int {
var add: Int {return self + 100} // Line A
}
extension Int {
var add: Int {return self + 105} //Line B
}
这样做会产生编译时错误(在B行上),表明:Invalid redeclaration of 'add'
Swift is a static typing language并帮助您在运行时
之前找到这类错误在Objective-C中你可以写这个并且仍然没有收到错误,但结果将是undefined,因为你不知道哪个方法首先被加载运行。
答案 1 :(得分:2)
在2个单独的扩展中两次覆盖单个协议方法将不起作用,因为协议方法名称将发生冲突。编译完成后,它们只是同一类的方法。考虑到这一点,也许将所有协议方法放在他们自己的扩展和放大器中。从其他人那里打电话给他们?
以下可能是一个通用选项。如果您决定继续添加其他扩展功能,可能会变得混乱。
class baseClass {
//stuff
}
extension baseClass: myProtocol {
override func myProtocolMethod(args) -> returnType {
//Repeat this in a separate extension & your method names collide
var status: Bool
//protocol method code sets status as appropriate...
return status = true ? optOne(status) : optTwo(status)
}
func optOne(status:Bool) -> returnType{
//do the 'true' thing
return returnType
}
func optTwo(status:Bool) -> returnType{
//do the 'false' thing
return returnType
}
}
extension baseClass {
var oneExtension = myProtocolMethod(someArg)
}
extension baseClass {
var twoExtension = myProtocolMethod(someArg)
}
答案 2 :(得分:1)
我意识到这个问题已经有一年多的历史了,原版海报可能已经转移到了其他方面,但我还是希望分享一个想法,或者得到一些反馈。
你说你想要一个可以多次覆盖的方法。简短的回答,就像这个帖子中的很多人所说的那样没有,但是长答案是是。
我们可以通过一些通用的魔法来解决这个问题。
class MyView: UIView {
var customizer: MyProtocol<MyView> = Defaults()
func willCallCustomizer() {
customizer.coolMethod(self)
}
}
// Use this class as if it were a protocol
class MyProtocol<T: UIView>: NSObject {
func coolMethod(_ view: T) {}
}
// Class inherits from the "protocol"
class Defaults: MyProtocol<MyView> {
override func coolMethod(_ view: MyView) {
// Some default behavior
}
}
///客户端......
class CustomerCustomizer: MyProtocol<MyView> {
override func coolMethod(_ view: MyView) {
// customized behavior
}
}
因此,如果客户想要使用他们自己的定制器,他们只需设置它,否则它只会使用默认定制器。
myViewInstance.customizer = CustomerCustomizer()
此方法的好处是客户端可以根据需要多次更改自定义程序对象。因为MyProtocol是通用的,所以它也可以用于其他UIView;从而履行协议的作用。