问题
I have an array called subscribers that stores objects which conform to the protocol JABPanelChangeSubscriber. The protocol is declared as
public protocol JABPanelChangeSubscriber {
}
and my array is declared as:
var subscribers = [JABPanelChangeSubscriber]()
Now I need to implement a method to add a subscriber to the list, but it first has to check that that subscriber has not already been added before.
public func addSubscriber(subscriber: JABPanelChangeSubscriber) {
if subscribers.find(subscriber) == nil { // This ensures that the subscriber has never been added before
subscribers.append(subscriber)
}
}
Unfortunately, JABPanelChangeSubscriber is not Equatable, and I can't figure out how to make it Equatable, so the find method is giving me an error. Can anyone help me out with a fix or with a suggestion for a different approach?
Thanks
回答1:
Assuming that all types implementing your protocol are reference types (classes), you can declare the protocol as a "class protocol"
public protocol JABPanelChangeSubscriber : class {
}
and use the identity operator ===
to check if the array already
contains an element pointing to the same instance as the given argument:
public func addSubscriber(subscriber: JABPanelChangeSubscriber) {
if !contains(subscribers, { $0 === subscriber } ) {
subscribers.append(subscriber)
}
}
回答2:
Add isEqualTo(:)
requirement to JABPanelChangeSubscriber
protocol
public protocol JABPanelChangeSubscriber {
func isEqualTo(other: JABPanelChangeSubscriber) -> Bool
}
Extension to JABPanelChangeSubscriber
protocol with Self
requirement
extension JABPanelChangeSubscriber where Self: Equatable {
func isEqualTo(other: JABPanelChangeSubscriber) -> Bool {
guard let other = other as? Self else { return false }
return self == other
}
}
Remember to make objects conform
Equatable
protocol too
class SomeClass: Equatable {}
func == (lhs: SomeClass, rhs: SomeClass) -> Bool {
//your code here
//you could use `===` operand
}
struct SomeStruct: Equatable {}
func == (lhs: SomeStruct, rhs: SomeStruct) -> Bool {
//your code here
}
Then find the index
func indexOf(object: JABPanelChangeSubscriber) -> Int? {
return subcribers.indexOf({ $0.isEqualTo(object) })
}
If you want to check the existence of an object before adding them to the array
func addSubscriber(subscriber: JABPanelChangeSubscriber) {
if !subscribers.contains({ $0.isEqualTo(subscriber) }) {
subscribers.append(subscriber)
}
}
来源:https://stackoverflow.com/questions/30344222/find-index-of-object-in-an-array-of-type-someprotocol