无法传递对指定了self的协议的引用

时间:2019-07-15 18:44:48

标签: ios swift

我有一个使用NVActivityIndicatorView库的项目,我试图从两个视图控制器中提取一些逻辑。两个视图控制器均符合NVActivityIndicatorViewable的定义,其定义为:

// From the libaray. I don't want to modify this.
public protocol NVActivityIndicatorViewable {}

public extension NVActivityIndicatorViewable where Self: UIViewController
{
    func startAnimating( ... ) { ... }
    func stopAnimating() { ... }
}

因此,我希望能够传递这些视图控制器之一,并在其上使用startAnimationstopAnimation方法。

func sharedLogic(sender: NVActivityIndicatorViewable)
{
    sender.startAnimating( ... )
    sender.stopAnimating()
}

但是,此操作因编译器错误'NVActivityIndicatorViewable' requires that 'NVActivityIndicatorViewable' inherit from 'UIViewController'

而失败

尝试使用sender: UIViewController进行此操作,这会失败,并出现编译时错误Value of 'UIViewController' has no member 'startAnimating',正如我所期望的那样。

func sharedLogic(sender: UIViewController) 
{
    sender.startAnimating( ... )
    sender.stopAnimating()
}

我发现了两种可能的解决方案:

  1. 创建一个空的子类,同时指定这两种类型:(此新类型不包含任何逻辑)
class ActivityIndicatorViewController: UIViewController, NVActivityIndicatorViewable { }
  1. 使用扩展名将所有视图控制器指定为活动指示器:(这会在许多类上导致redundant conformance错误)
extension UIViewController: NVActivityIndicatorViewable { }

我可以在不创建新类型的情况下完成此操作吗?

环境设置:

  • Xcode版本:10.1
  • iOS部署目标:9.0
  • 快速版本:3

2 个答案:

答案 0 :(得分:1)

您在协议上设置了约束并扩展了受约束的协议。因此,如果要使用这两个功能,则需要一个符合协议的UIViewContoller

将功能移至原始协议以获取所需的内容。

public protocol NVActivityIndicatorViewable {
    func startAnimating( ... )
    func stopAnimating()
}

由于评论而更新:

如果要保持原始协议不变,请对该功能使用合成类型:

func sharedLogic(sender: UIViewController & NVActivityIndicatorViewable) {
    sender.startAnimating()
    sender.stopAnimating()
} 

答案 1 :(得分:1)

这里想要的是composition type-一种既继承自UIViewController并符合NVActivityIndicatorViewable的类型:

UIViewController & NVActivityIndicatorViewable

您可以将其直接用作方法的参数类型:

func sharedLogic(sender: UIViewController & NVActivityIndicatorViewable)

或者您可以为其创建一个typealias(尽管我想不出一个简短的名字):

typealias SomeShorterName = UIViewController & NVActivityIndicatorViewable

然后您可以使用SomeShorterName作为参数类型。