Ios 仅当类符合特定协议时才对其进行快速扩展
Hi there=)我刚刚遇到一个设计问题,我需要(基本上)做以下工作: 我想在Ios 仅当类符合特定协议时才对其进行快速扩展,ios,swift,uiviewcontroller,swift-protocols,swift-extensions,Ios,Swift,Uiviewcontroller,Swift Protocols,Swift Extensions,Hi there=)我刚刚遇到一个设计问题,我需要(基本上)做以下工作: 我想在视图中插入一点代码,它将出现在任何UIViewController子类的子类中,该子类符合协议MyProtocol。代码说明: protocol MyProtocol { func protocolFunction() { //do cool stuff... } } extension UIViewController where Self: MyProtocol //<--
视图中插入一点代码,它将出现在任何UIViewController
子类的子类中,该子类符合协议MyProtocol
。代码说明:
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
}
}
协议MyProtocol
{
func协议函数(){
//做些很酷的事。。。
}
}
扩展UIViewController where Self:MyProtocol/到目前为止,我还没有找到真正令人满意的方法,但我决定发布我最终为这个特定问题所做的工作。
简而言之,解决方案如下(使用原始示例代码):
缺点:
- 不是做事的“快捷方式”
- swizzling方法将被调用并在所有
UIViewControllers
上生效,即使我们只验证那些符合MyProtocol
协议的方法来运行敏感的代码行
我非常希望它能帮助其他面临类似情况的人=)你已经接近解决方案了。只是需要换个方向。仅当协议是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
}
}
为什么不使用简单继承呢?它非常适合覆盖默认类方法。嘿@MaxPevsner谢谢你的评论!=)我选择不使用继承,因为我正在构建一个用于多个项目的系统,并且我不希望API强制每个项目的UIViewController从特定的超类继承(“因为可能每个项目都需要自己的基类”),所以如果可能的话,我希望避免这种情况。我相信,你在这里漏掉了一点。但是这个讨论远远超出了这个问题的范围。嘿,谢谢你的回答=)这个问题就是我在描述中所说的:“如果我们改为扩展协议,我们可以在Self:UIViewController中添加条件扩展MyProtocol,但我们不能重写协议扩展中类的方法,这意味着我们不能公共重写swizzling所需的类func initialize()。”
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
}
}