我有一个iOS框架,我正在升级到Swift 3. 我希望API的方法签名遵循Swift 3约定,即在保持向后兼容性的同时使用方法的第一个命名参数。 / strong>添加新的API方法签名并弃用旧签名很容易。但是,使用委托中使用的协议处理此问题的最佳方法是什么?
Swift 2.x的API:
@objc(FooManager)
public class FooManager {
public var delegate: FooManagerDelegate?
public func saveFoo(foo: Foo) {
...
delegate?.didSaveFoo(foo)
}
...
}
@objc public protocol FooManagerDelegate {
@objc optional func didSaveFoo(foo: Foo)
}
Swift 3.x的新API:
@objc(FooManager)
public class FooManager {
public var delegate: FooManagerDelegate?
@available(*, deprecated, message: "use didSave(foo: foo)")
public func saveFoo(foo: Foo) {
...
delegate?.didSaveFoo(foo)
}
public func save(foo: Foo) {
...
delegate?.didSave(foo: foo)
}
...
}
@objc public protocol FooManagerDelegate {
@objc optional func didSaveFoo(foo: Foo)
@objc optional func didSave(foo: Foo)
}
上述解决方案可行,但不会向用户提供任何弃用警告,以便继续使用旧的委托方法。我可以创建一个新的委托并弃用旧的委托类,但最后我必须拥有非标准的委托类和属性命名。我讨厌让我的FooManager看起来像这样丑陋:
public class FooManager {
@available(*, deprecated, message: "use swift3delegate")
public var delegate: FooDelegate?
public var swift3delegate: Swift3FooDelegate?
是否有更好的解决方案,用于将用户迁移到新的协议方法签名,同时保持向后兼容性?
答案 0 :(得分:2)
根据我的知识,究竟你要求的是Swift(也不是Objective-C?)。引用response to a related question:
在符合MyProtocol并实现myOldFunction()的任何类上抛出弃用警告的主要问题是,实现不属于您的协议的函数和属性的类没有任何问题。
也就是说,不推荐使用协议的方法并不一定意味着方法蓝图是普遍要避免的,它只是意味着为了符合该协议,方法或有问题的财产现已弃用。
我完全明白了这一点,我也喜欢这个功能,但据我所知,Swift 3至少不提供它(据我所知,Objective-C也没有)。
对此的一个解决方案是弃用整个协议,并生成一个新协议,您需要在Swift 3代码中声明一致性。所以,这有效:
@available(*, deprecated, message="use ModernX instead")
protocol X {}
class A: X {}
...并且在您的ModernX
协议中,只包含除已弃用方法之外的所有方法。使用没有弃用方法的基本协议可以使这个稍微不那么笨重,但它肯定是一个很好的样板很重要的解决方法:
protocol BaseX {
func foo()
func bar()
}
@available(*, deprecated, message: "Use ModernX instead")
protocol X: BaseX {
func theDeprecatedFunction()
}
protocol ModernX: BaseX {
func theModernFunction()
}
// you'll get a deprecation warning here.
class A: X {
func foo() {}
func bar() {}
func theDeprecatedFunction() {
}
}