![](/img/trans.png)
[英]Swift - extending a class only when it conforms to a protocol to use method swizzling
[英]Swift extension of a class ONLY when it conforms to a specific protocol
嗨那里=)我刚刚面临一个设计问题,我需要(基本上)做以下事情:
我想在viewWillAppear:
上注入一些代码viewWillAppear:
任何符合协议MyProtocol
UIViewController
子类 。 在代码中解释:
protocol MyProtocol
{
func protocolFunction() {
//do cool stuff...
}
}
extension UIViewController where Self: MyProtocol //<-----compilation error
{
public override class func initialize()
{
//swizzling stuff switching viewWillAppear(_: Bool) with xxx_viewWillAppear(animated: Bool)
}
// MARK: - Swizzling
func xxx_viewWillAppear(animated: Bool)
{
self.xxx_viewWillAppear(animated)
//invoke APIs from
self.protocolFunction() // MyProtocol APIs
let viewLoaded = self.isViewLoaded // UIViewController APIs
}
}
这里的主要问题是我需要UIVIewController
扩展中的两件事:
MyProtocol
和UIViewController
API UIViewController
方法initialize()
以便能够swizzle viewWillAppear:
这两个功能似乎不兼容(从Swift 3开始),因为:
extension UIViewController where Self: MyProtocol
) extension MyProtocol where Self: UIViewController
添加条件extension MyProtocol where Self: UIViewController
但是我们不能覆盖协议扩展中类的方法 ,这意味着我们不能public override class func initialize()
swizzling所需的public override class func initialize()
。 所以我想知道是否有人可以为我面临的这个问题提供Swifty解决方案? =)
提前致谢!!
你接近解决方案。 只需要另辟蹊径。 仅在UIViewController的一部分时扩展协议。
protocol MyProtocol
{
func protocolFunction() {
//do cool stuff...
}
}
extension MyProtocol where Self: UIViewController {
public override class func initialize()
{
//swizzling stuff switching viewWillAppear(_: Bool) with xxx_viewWillAppear(animated: Bool)
}
// MARK: - Swizzling
func xxx_viewWillAppear(animated: Bool)
{
self.xxx_viewWillAppear(animated)
//invoke APIs from
self.protocolFunction() // MyProtocol APIs
let viewLoaded = self.isViewLoaded // UIViewController APIs
}
}
好吧,到目前为止,我没有找到真正令人满意的方法,但我决定发布我最后为这个特定问题做的事情。 简而言之,解决方案是这样的(使用原始示例代码):
protocol MyProtocol
{
func protocolFunction() {
//do cool stuff...
}
}
extension UIViewController //------->simple extension on UIViewController directly
{
public override class func initialize()
{
//swizzling stuff switching viewWillAppear(_: Bool) with xxx_viewWillAppear(animated: Bool)
}
// MARK: - Swizzling
func xxx_viewWillAppear(animated: Bool)
{
self.xxx_viewWillAppear(animated)
//------->only run when self conforms to MyProtocol
if let protocolConformingSelf = self as? MyProtocol {
//invoke APIs from
protocolConformingSelf.protocolFunction() // MyProtocol APIs
let viewLoaded = protocolConformingSelf.isViewLoaded // UIViewController APIs
}
}
}
缺点:
UIViewControllers
生效,即使我们只验证那些符合MyProtocol
协议的运行敏感代码行的方法。 我非常希望它可以帮助那些面临类似情况的人=)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.