在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中的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 } }