在swift代表中查找委托

我想在删除之前检查我的removeDelegate方法是否已经有一个委托。 我怎么做?

这是迄今为止我所得到的:

protocol LocationManagerDelegate { func locationManagerDidUpdateLocation( oldLocation: CLLocationCoordinate2D, currentLocation: CLLocationCoordinate2D ) } class LocationManager: NSObject { private var _delegates = [LocationManagerDelegate]() func removeDelegate(delegate:LocationManagerDelegate) { if contains(_delegates, delegate) { // Remove delegate } } } 

但是,这给了我'包含'行上的以下错误:

不能用types'(@lvalue数组<LocationManagerDelegate> !, LocationManagerDelegate)'的参数列表调用'contains''

Swift 3的更新:

假设委托实际上是一个类的实例,你可以通过从“class”中“inheritance”来在协议中要求:

 protocol LocationManagerDelegate: class { // ... } 

然后使用index(where:)方法,使用“indentitiy operator ===

 class LocationManager: NSObject { private var _delegates = [LocationManagerDelegate]() func removeDelegate(delegate:LocationManagerDelegate) { if let index = _delegates.index(where: { $0 === delegate }) { _delegates.remove(at: index) } } } 

老答案(斯威夫特1):

有两个略有不同的contains()函数:

 func contains<S : SequenceType where S.Generator.Element : Equatable>(seq: S, x: S.Generator.Element) -> Bool func contains<S : SequenceType, L : BooleanType>(seq: S, predicate: (S.Generator.Element) -> L) -> Bool 

您使用的是第一个,它要求序列元素符合Equatable协议,即它们可以与==比较。

假设委托实际上是一个类的实例,你可以通过从“class”中“inheritance”来在协议中要求:

 protocol LocationManagerDelegate : class { // ... } 

然后使用第二个基于谓词的版本contains()与身份运算符===

 func removeDelegate(delegate:LocationManagerDelegate) { if contains(_delegates, { $0 === delegate }) { // Remove delegate } } 

要从数组中删除对象,你必须得到它的索引,所以你可以使用https://stackoverflow.com/a/25543084/1187415中&#x7684;findIdenticalObject()函数:

 func findIdenticalObject<T : AnyObject>(array: [T], value: T) -> Int? { for (index, elem) in enumerate(array) { if elem === value { return index } } return nil } 

然后find并从数组中删除

 func removeDelegate(delegate:LocationManagerDelegate) { if let index = findIdenticalObject(_delegates, delegate) { _delegates.removeAtIndex(index) } } 

contains的参数必须实现Equatable协议,因为它被定义为:

 public func contains<T:Equatable>(left:[T], right:T) -> Bool 

由于没有办法表明LocationManagerDelegate实现了Equatable,我不认为你可以使用它。 显而易见的尝试是:

 protocol LocationManagerDelegate : Equatable { ... } 

但是,当您尝试声明数组时,这会失败,因为Equatable使用Self。

我能想到的最佳select是:

 func removeDelegate(delegate:LocationManagerDelegate) { _delegates = filter(_delegates) { return $0 !== delegate } }