快速符合多种协议的类型


77

我有一个符合多种协议的Objective-C变量。

id <NSObject, NSCopying, NSCoding> identityToken; 

我将如何在Swift中代表这种类型?

Answers:


151

这应该工作:

var identityToken: NSObjectProtocol & NSCopying & NSCoding 

请注意,必须快速使用NSObjectProtocol而不是NSObject。

以下是一些其他示例:

符合多种协议的对象数组:

var array: [NSObjectProtocol & NSCopying & NSCoding]

具有符合多种协议的参数的功能:

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

}

对于3.1之前的Swift版本,请使用:

var identityToken: (NSObjectProtocol, NSCopying, NSCoding)

1
您能否详细说明为什么NSObjectProtocol必须使用?
aleclarson 2014年

1
@aleclarson在Objective-c中有一个NSObject类和协议。Swift使用NSObject和NSObjectProtocol来区分两者。
康纳2014年

8
很酷。并不知道这种语法(有点尴尬)。但是,如何使用显式类(例如在obj-c:中)MyClass<ProtcolOne, ProtocolTwo>呢?
devios1 2014年

4
@devios您可以使用泛型来替换MyClass <ProtocolOne,ProtocolTwo>:func foo <T:MyClass,其中T:protocol <ProtocolOne,ProtocolTwo >>(参数:T)
Oscar

3
@Oscar感谢您的有用提示。如何将MyClass <ProtocolOne,ProtocolTwo>声明为变量?
伊利亚斯·卡里姆

11

迅捷3

var idToken: NSObjectProtocol & NSCopying & NSCoding

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

5

似乎您也可以对复合协议进行类型别名,如果您打算多次使用相同的协议组合,这可能会派上用场。

typealias IDToken = NSObjectProtocol & NSCopying & NSCoding

与示例相同的示例,使用类型别名:

var idToken: IDToken

var array: [IDToken] = []

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

4

以上来自conner的回答是正确的,但是,如果您以后想要添加其他协议方法或更改顶级协议,则通常应该实现一个单独的协议,该协议本身可以从其他协议继承而来。

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

然后利用:

var identityToken : MyOtherProtocol

0

对于泛型,这也适用:

func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource & UICollectionViewDelegate>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.