Search code examples
swiftgenericsweak-references

Compare / Equatable weak generics in Swift


I want to create an array of weak referenced delegates like so...

fileprivate class WeakDelegate<T:AnyObject> {

    weak var value:T?

    init (value:T) {
        self.value = value
    }
}


class Radio {

    private var delegates = [WeakDelegate<AnyObject>]()
}

So far so good...? what I'd like to do also is tidy up my array in these two ways...

1.

func removeDeadDelegates() {

    let liveDelegates = delegates.filter { $0.value != nil }
    delegates = liveDelegates
}

and 2.

func remove<T>(specificDelegate:T) {

    let filteredDelegates = delegates.filter { $0.value != specificDelegate }
    listeners = filteredDelegates
}

Says Cannot convert value of type 'T' to expected argument type '_OptionalNilComparisonType'

Now I can just add this to make the warning go away like this...

    let liveDelegates = delegates.filter {

        if let d = specificDelegate as? _OptionalNilComparisonType {
            return $0.value != d
        }

        return true
    }

but this cast doesn't work...

I'm concerned because I'm not sure what this means... can anyone explain why I can't compare generics with == and why this cast is failing?

Thanks for your time

EDIT

Like this?

func remove<T:AnyObject>(delegate:T) {

    let filteredDelegates = delegates.filter { $0.value != delegate }
    delegates = filteredDelegates
}

No joy sadly...


Solution

  • Instances of a class type can be compared with the “identical to” === and “not identical to” !== operators:

    func remove(specificDelegate: AnyObject) {
        let filteredDelegates = delegates.filter { $0.value !== specificDelegate }
        delegates = filteredDelegates
    }
    

    The same works for a generic method

    func remove<T:AnyObject>(specificDelegate: T) {
        let filteredDelegates = delegates.filter { $0.value !== specificDelegate }
        delegates = filteredDelegates
    }
    

    (but I do not yet see the advantage of doing so).