我想在删除之前检查我的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
}
}
}
但是,这会在' if contains'上给出以下错误。 line:
无法调用'包含'使用类型'的参数列表(@ lvalue Array< LocationManagerDelegate>!,LocationManagerDelegate)'
答案 0 :(得分:11)
Swift 3的更新:
假设委托实际上是类的实例,您可以在协议中要求"继承"来自" class":
protocol LocationManagerDelegate: class {
// ...
}
然后使用" indentitiy运算符使用index(where:)
方法
===
:
class LocationManager: NSObject {
private var _delegates = [LocationManagerDelegate]()
func removeDelegate(delegate:LocationManagerDelegate) {
if let index = _delegates.index(where: { $0 === delegate }) {
_delegates.remove(at: index)
}
}
}
旧答案(Swift 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
协议,即可以与==
进行比较。
假设委托实际上是类的实例,您可以要求 在协议中通过&#34;继承&#34;来自&#34; class&#34;:
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
}
然后使用
查找并从数组中删除func removeDelegate(delegate:LocationManagerDelegate) {
if let index = findIdenticalObject(_delegates, delegate) {
_delegates.removeAtIndex(index)
}
}
答案 1 :(得分:1)
contains
的参数必须实现Equatable协议,因为它被定义为:
public func contains<T:Equatable>(left:[T], right:T) -> Bool
由于没有办法表明LocationManagerDelegate
实现了Equatable,我认为你不能使用它。显而易见的尝试是:
protocol LocationManagerDelegate : Equatable {
...
}
但是当你尝试声明数组时会失败,因为Equatable使用Self。
我能想出的最佳选择是:
func removeDelegate(delegate:LocationManagerDelegate) {
_delegates = filter(_delegates) { return $0 !== delegate }
}