I want to check if I already have a delegate in my removeDelegate method before removing. How do I do that?
Here's what I've got so far:
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
        }
    }
}
However, this gives me the following error on the 'if contains' line:
cannot invoke 'contains' with an argument list of type '(@lvalue Array< LocationManagerDelegate >!, LocationManagerDelegate)'
Update for Swift 4.2:
Assuming that the delegates are actually instances of a class, you could require that in the protocol by "inheriting" from "class":
protocol LocationManagerDelegate: class {
    // ...
}
and then use the firstIndex(where:) method, using the "identity operator
===:
class LocationManager: NSObject {
    private var _delegates = [LocationManagerDelegate]()
    
    func removeDelegate(delegate:LocationManagerDelegate) {
        if let index = _delegates.firstIndex(where: { $0 === delegate }) {
            _delegates.remove(at: index)
        }
    }
}
Old answer (Swift 1):
There are two slightly different contains() functions:
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
You are using the first one, which requires that the sequence elements conform to
the Equatable protocol, i.e. they can be compared with ==.
Assuming that the delegates are actually instances of a class, you could require that in the protocol by "inheriting" from "class":
protocol LocationManagerDelegate : class {
    // ...
}
and then use the second, predicate-based version of contains() with the
identity operator ===:
func removeDelegate(delegate:LocationManagerDelegate) {
    if contains(_delegates, { $0 === delegate }) {
        // Remove delegate
    }
}
To remove the object from the array you'll have to get its index, so you might use
the findIdenticalObject() function from https://stackoverflow.com/a/25543084/1187415:
func findIdenticalObject<T : AnyObject>(array: [T], value: T) -> Int? {
    for (index, elem) in enumerate(array) {
        if elem === value {
            return index
        }
    }
    return nil
}
and then find and remove from the array with
func removeDelegate(delegate:LocationManagerDelegate) {
    if let index = findIdenticalObject(_delegates, delegate) {
        _delegates.removeAtIndex(index)
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With