在Objective-C中,可以编写类似的东西:
@property(retain) UIView<Protocol1, Protocol2, ...> *myView;
Run Code Online (Sandbox Code Playgroud)
但是如何在swift中编写这段代码呢?
我已经知道如何使属性符合许多协议,但它不能使用继承:
var myView: ??? protocol<Protocol1, Protocol2, ...>
Run Code Online (Sandbox Code Playgroud)
编辑:
我使用许多UIView子类型UIImageView,UILabel或者其他类型,我需要使用一些UIView属性以及协议中定义的一些方法.在最坏的情况下,我可以UIViewProtocol使用所需的属性创建一个,但我知道在Swift中是否可以声明一个属性/变量,其类型和一些协议符合.
Mik*_*e S 25
您可以使用where子句对泛型类执行此操作:
where子句使您能够要求关联类型符合某个协议,和/或某些类型参数和相关类型是相同的.
要使用它,请在具有类型约束的泛型类中定义属性,以检查属性的类型参数是否与所需的基类和协议匹配.
对于您的具体示例,它可能看起来像这样:
class MyViewController<T where T: UIView, T: Protocol1, T: Protocol2>: UIViewController {
var myView: T
// ...
}
Run Code Online (Sandbox Code Playgroud)
在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 :)
}
Run Code Online (Sandbox Code Playgroud)
一个也可能有点丑陋的方法之一是创建一个包装器协议UIView:
protocol UIViewRef {
var instance: UIView { get }
}
Run Code Online (Sandbox Code Playgroud)
现在可以创建一个实现的协议Protocol1,Protocol2并且UIViewRef将用于获取UIView自身:
protocol MyUIViewProtocol: UIViewRef, Protocol1, Protocol2 { }
Run Code Online (Sandbox Code Playgroud)
最后一步将为您的UIViews 实现UIViewRef协议,在您的情况下,据我所知,已经实现Protocol1并且Protocol2:
// SomeOfMyViews already implements Protocol1 and Protocol2
extension SomeOfMyUIViews: MyUIViewProtocol {
var instance: UIView { return self }
}
Run Code Online (Sandbox Code Playgroud)
作为我们的结果MyUIViewProtocol,其实施者持有对a的引用,UIView并且每个实现Protocol1和实现
Protocol2.但有一点需要注意 - 为了得到它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) }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5901 次 |
| 最近记录: |