Typen, die schnell mehreren Protokollen entsprechen


77

Ich habe eine Objective-C-Variable, die mehreren Protokollen entspricht.

id <NSObject, NSCopying, NSCoding> identityToken; 

Wie würde ich diesen Typ in Swift darstellen?

Antworten:


151

Das sollte funktionieren:

var identityToken: NSObjectProtocol & NSCopying & NSCoding 

Beachten Sie, dass Sie schnell NSObjectProtocol anstelle von NSObject verwenden müssen.

Hier einige zusätzliche Beispiele:

Array von Objekten, die mehreren Protokollen entsprechen:

var array: [NSObjectProtocol & NSCopying & NSCoding]

Funktion mit einem Parameter, der mehreren Protokollen entspricht:

func foo(param: NSObjectProtocol & NSCopying & NSCoding) {

}

Verwenden Sie für die Swift-Version vor 3.1:

var identityToken: (NSObjectProtocol, NSCopying, NSCoding)

1
Können Sie erläutern, warum NSObjectProtocolverwendet werden muss?
Aleclarson

1
@aleclarson In Objective-C gibt es eine NSObject-Klasse und ein NSObject-Protokoll. Swift verwendet NSObject und NSObjectProtocol, um zwischen beiden zu unterscheiden.
Connor

8
Sehr cool. War sich dieser (etwas umständlichen) Syntax nicht bewusst. Wie können Sie dies jedoch auch mit einer expliziten Klasse tun, beispielsweise in obj-c : MyClass<ProtcolOne, ProtocolTwo>?
Devios1

4
@devios Sie können MyClass <ProtocolOne, ProtocolTwo> durch Generika ersetzen: func foo <T: MyClass wobei T: protocol <ProtocolOne, ProtocolTwo >> (params: T)
Oscar

3
@ Oscar danke für den hilfreichen Tipp. Wie kann man MyClass <ProtocolOne, ProtocolTwo> als Variable deklarieren?
Ilias Karim

11

Swift 3

var idToken: NSObjectProtocol & NSCopying & NSCoding

func foo(_ delegateAndDataSource: UICollectionViewDelegate & UICollectionViewDataSource) { ... }

5

Anscheinend können Sie auch die zusammengesetzten Protokolle als Alias ​​eingeben, was nützlich sein kann, wenn Sie dieselbe Protokollkombination mehrmals verwenden möchten.

typealias IDToken = NSObjectProtocol & NSCopying & NSCoding

Gleiche Beispiele wie in der akzeptierten Antwort unter Verwendung eines Typ-Alias:

var idToken: IDToken

var array: [IDToken] = []

func foo(param: IDToken) { ... }

4

Die obige Antwort von conner ist richtig. Sie sollten jedoch häufig ein separates Protokoll implementieren, das selbst von den anderen Protokollen erbt und Ihnen mehr Flexibilität bietet, wenn Sie später zusätzliche Protokollmethoden hinzufügen oder die Protokolle der obersten Ebene ändern möchten.

internal protocol MyOtherProtocol : NSObjectProtocol, NSCopying, NSCoding {
    func someOtherNecessaryMethod()
}

Dann verwendet:

var identityToken : MyOtherProtocol

0

Für Generika funktioniert dies auch:

func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource & UICollectionViewDelegate>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.