Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/101.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 仅当类符合特定协议时才对其进行快速扩展_Ios_Swift_Uiviewcontroller_Swift Protocols_Swift Extensions - Fatal编程技术网

Ios 仅当类符合特定协议时才对其进行快速扩展

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 //<--

Hi there=)我刚刚遇到一个设计问题,我需要(基本上)做以下工作:

我想在
视图中插入一点代码,它将出现在任何
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
  }
}