我有一个iOS框架,我正在升级到Swift 3。我希望API的方法签名遵循Swift 3惯例,即在保持向后兼容性的同时为方法使用第一个命名参数。添加新的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)
}
上面的解决方案可以工作,但是它不会因为用户继续使用旧的委托方法而给他们任何不推荐的警告。我可以创建一个新的委托并弃用旧的委托类,但最后不得不使用非标准的委托类和属性命名。我不想让我的美食家看起来这么丑:
public class FooManager {
@available(*, deprecated, message: "use swift3delegate")
public var delegate: FooDelegate?
public var swift3delegate: Swift3FooDelegate?
在保持向后兼容性的同时,是否有更好的解决方案将用户迁移到新的协议方法签名?
最佳答案
在Swift(也不是Objective-C?)据我所知。引用aresponse 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() {
}
}
关于swift - 弃用Swift 3升级协议(protocol),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40028519/