Objective-Cでは、次のように書くことができます。
@property(retain) UIView<Protocol1, Protocol2, ...> *myView;
しかし、どうすればこのコードをすばやく書くことができますか?
プロパティを多くのプロトコルに準拠させる方法はすでに知っていますが、継承を使用しても機能しません。
var myView: ??? protocol<Protocol1, Protocol2, ...>
編集:
UIView
、UIImageView
などの多くのUILabel
サブタイプを使用しており、いくつかのUIView
プロパティとプロトコルで定義されたいくつかのメソッドを使用する必要があります。最悪の場合、必要なプロパティを使用してUIViewProtocol
を作成できますが、Swiftで、型とプロトコルを使用してプロパティ/変数を宣言できるかどうかはわかります。準拠する。
where句 を使用して、ジェネリッククラスでこれを行うことができます。
Where句を使用すると、関連付けられた型が特定のプロトコルに準拠していること、および/または特定の型パラメータと関連付けられた型が同じであることを要求できます。
これを使用するには、プロパティが 型制約 のジェネリッククラスで定義されているクラスを作成し、プロパティの 型パラメータ が目的の基本クラスとプロトコルに一致するかどうかを確認します。
特定の例では、次のようになります。
class MyViewController<T where T: UIView, T: Protocol1, T: Protocol2>: UIViewController {
var myView: T
// ...
}
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 :)
}
これを行う方法の1つで、おそらく少し醜いものは、UIView
のラッパープロトコルを作成することです。
protocol UIViewRef {
var instance: UIView { get }
}
これで、Protocol1
、Protocol2
、およびUIViewRef
を実装するプロトコルを作成できます。これは、UIView
自体を取得するために使用されます。
protocol MyUIViewProtocol: UIViewRef, Protocol1, Protocol2 { }
そして最後のステップは、UIView
sにUIViewRefプロトコルを実装することです。これは、私が理解しているように、すでにProtocol1
とProtocol2
を実装しています。
// SomeOfMyViews already implements Protocol1 and Protocol2
extension SomeOfMyUIViews: MyUIViewProtocol {
var instance: UIView { return self }
}
その結果、MyUIViewProtocol
があり、その実装者はUIView
への参照を保持し、それぞれがProtocol1
とProtocol2
を実装します。ただし、注意点が1つあります。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) }