In Objective-C ist es möglich, eine Klasse, die einem Protokoll entspricht, als Methodenparameter anzugeben. Zum Beispiel könnte ich eine Methode haben, die nur eine erlaubt UIViewController
, die konform ist mit UITableViewDataSource
:
- (void)foo:(UIViewController<UITableViewDataSource> *)vc;
Ich kann in Swift keinen Weg finden, dies zu tun (vielleicht ist es noch nicht möglich). Sie können mehrere Protokolle mit angeben func foo(obj: protocol<P1, P2>)
, aber wie benötigen Sie, dass das Objekt auch einer bestimmten Klasse angehört?
Antworten:
Sie können
foo
eine generische Funktion definieren und Typeinschränkungen verwenden, um sowohl eine Klasse als auch ein Protokoll zu benötigen.Swift 4
Swift 3 (funktioniert auch für Swift 4)
Swift 2
quelle
protocol<>
bereitgestellt wird (protocol<>
kann aber keine Nicht-Protokolltypen enthalten).numberOfSectionsInTableView
Sie aus Neugier nicht explizit auspacken, weil dies eine erforderliche Funktion istUITableViewDataSource
?numberOfSectionsInTableView:
ist optional - Sie könnten daran denkentableView:numberOfRowsInSection:
.func foo<T: UIViewController>(vc:T) where T:UITableViewDataSource { ... }
In Swift 4 können Sie dies mit dem neuen & -Zeichen erreichen:
quelle
In der Swift-Buchdokumentation wird vorgeschlagen, Typeinschränkungen mit einer where-Klausel zu verwenden:
Dies garantiert, dass "inParam" vom Typ "SomeClass" ist, mit der Bedingung, dass es auch "SomeProtocol" einhält. Sie können sogar mehrere where-Klauseln angeben, die durch ein Komma getrennt sind:
quelle
Mit Swift 3 können Sie Folgendes tun:
quelle
Was ist mit diesem Weg?:
quelle
Swift 5:
Also im Wesentlichen Jeroens Antwort oben.
quelle
Anmerkung im September 2015 : Dies war eine Beobachtung in den frühen Tagen von Swift.
Es scheint unmöglich zu sein. Apple hat diesen Ärger auch in einigen seiner APIs. Hier ist ein Beispiel aus einer neu eingeführten Klasse in iOS 8 (ab Beta 5):
UIInputViewController
'stextDocumentProxy
Eigentum:In Ziel-C wie folgt definiert:
und in Swift:
Link zur Dokumentation von Apple: https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UIInputViewController_Class/index.html#//apple_ref/occ/instp/UIInputViewController/textDocumentProxy
quelle
var textDocumentProxy: UITextDocumentProxy! { get }
@protocol MyAwesomeCallbacks <NSObject>