Swift:属性符合特定类,同时符合多个协议

时间:2014-09-10 13:47:47

标签: swift protocols

在Objective-C中,可以编写类似的东西:

@property(retain) UIView<Protocol1, Protocol2, ...> *myView;

但是如何在swift中编写这段代码?

我已经知道如何使属性符合许多协议,但是使用继承它不起作用:

var myView: ??? protocol<Protocol1, Protocol2, ...>

修改

我使用了许多UIView个子类型,例如UIImageViewUILabel或其他,我需要使用一些UIView属性以及协议中定义的一些方法。在最坏的情况下,我可以创建一个具有所需属性的UIViewProtocol,但我知道在Swift中是否可以使用类型和某些协议来声明属性/变量。

3 个答案:

答案 0 :(得分:25)

您可以使用where clause

对通用类执行此操作
  

使用where子句可以要求关联的类型符合   到某个协议,和/或某些类型参数和   相关类型是相同的。

要使用它,请在具有type constraint的泛型类中定义属性,以检查属性的type parameter是否与所需的基类和协议匹配。

对于您的具体示例,它可能看起来像这样:

class MyViewController<T where T: UIView, T: Protocol1, T: Protocol2>: UIViewController {
    var myView: T

    // ...
}

答案 1 :(得分:6)

在Swift 4中,它终于有可能了。您可以同时声明某些符合协议的类的变量,如下所示:

class ClassA {
    var someVar: String?
}

protocol ProtocolA {}

class ClassB {
    var someOptional: (ClassA & ProtocolA)? // here is optional value
    var some: ClassA & ProtocolA // here is non-optional value; need to provide init though :)
}

答案 2 :(得分:5)

UIView创建一个包装协议,其中一个可能有点丑陋的方法是:

protocol UIViewRef {
    var instance: UIView { get }
}

现在可以创建一个实现Protocol1Protocol2UIViewRef的协议,该协议将用于获取UIView本身:

protocol MyUIViewProtocol: UIViewRef, Protocol1, Protocol2 { }

最后一步将为您的UIView实施UIViewRef协议,根据您的理解,我已经实现了Protocol1Protocol2

// SomeOfMyViews already implements Protocol1 and Protocol2
extension SomeOfMyUIViews: MyUIViewProtocol {
    var instance: UIView { return self }
}

结果我们有MyUIViewProtocol,其实施者持有UIView的引用,并且每个实现者都实现 Protocol1Protocol2。但有一点需要注意 - 要获得UIView本身,我们需要从instance询问它的引用 属性。例如

// Lets say we're somewhere in a UIViewController
var views: [SomeOfMyUIView] = // Get list of my views
views.forEach { self.view.addSubview($0.instance) }