Swift 3升级的弃用协议 [英] Deprecating protocols for Swift 3 upgrade

查看:183
本文介绍了Swift 3升级的弃用协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个我正在升级到Swift 3的iOS框架。我希望API的方法签名符合使用第一个命名参数的Swift 3约定,同时保持向后兼容性。足够容易添加新的API方法签名,并弃用旧的API方法签名。但是在代理中使用协议的最佳方式是什么?

I have an iOS framework that I am upgradding to Swift 3. I would like the API's method signatures to follow the Swift 3 conventions of using a first named parameter for methods while maintaining backward compatibility. It's easy enough to add new API method signatures and deprecate the old ones. But what is the best way to handle this with protocols that are used in delegates?

Swift 2.x的API:

API for Swift 2.x:

 @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:

New API for Swift 3.x:

 @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看起来很丑陋:

The above solution will work, but it won't give any deprecation warnings to users for continuing to use the old delegate methods. I could create a new delegate and deprecate the old delegate class, but then I end up with having to have non-standard delegate class and property naming. I'd hate to have my FooManager look ugly like this:

 public class FooManager {
   @available(*, deprecated, message: "use swift3delegate")
   public var delegate: FooDelegate?
   public var swift3delegate: Swift3FooDelegate?

是否有任何更好的解决方案将用户迁移到新的协议方法签名,维持向后兼容性?

Are there any better solutions for migrating users to new protocol method signatures while maintaining backward compatibility?

推荐答案

正是在Swift(和Objective-C?)中,您所要求的是不可能的。引用回复相关问题

Exactly what you are asking for is not possible in Swift (nor Objective-C?) to my knowledge. Quoting a response to a related question:


在符合MyProtocol和实现myOldFunction()的任何类上抛出抛弃警告的主要问题是实现不属于协议的函数和属性的类没有错误。

The primary problem with throwing a deprecation warning on any class which conforms to MyProtocol and implemented myOldFunction() is that there's nothing wrong with classes implementing functions and properties that are not part of your protocol.

也就是说,不推荐使用协议的方法不一定意味着方法蓝图是普遍被避免的,这可能意味着为了符合对于该协议,现在不推荐使用该方法或属性。

That is, that the protocol's method is deprecated wouldn't necessarily mean that the method blueprint is universally to be avoided, it could just mean that for the purposes of conformance to that protocol, the method or property in question is now deprecated.

我完全看到了这一点,我也想要这个功能,但据我所知,Swift 3至少不提供它(Objective-C也不我的知识)。

I totally see the point for this and I'd like this feature too, but to my knowledge Swift 3 at least does not offer it (neither does Objective-C to my knowledge).

一个解决方案是弃用整个协议,并产生一个新协议,您需要声明符合Swift 3代码的一致性。所以,这样做:

One solution for this would be to deprecate the entire protocol, and produce a new protocol you need to declare conformance to in your Swift 3 code. So, this works:

@available(*, deprecated, message="use ModernX instead")
protocol X {}

class A: X {}

...在你的 ModernX 协议只包括除了不推荐使用的方法之外的所有方法。使用不使用弃用方法的基本协议可能会使这个稍微不那么笨重,但它是一个很好的样板很重的解决方法:

… and in your ModernX protocol simply include all the methods except for the deprecated method(s). Using a base protocol without the deprecated method could make this slightly less clunky, but it is a pretty boilerplate heavy workaround for sure:

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 3升级的弃用协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆