Protocols and Equality

I recently found myself in the position where I am happily using a protocol, and needed to work with equality in a context that can be summed up as:

var currentObject: MyProtocol = Thing1() {
willSet{
if newValue != currentObject {
//perform costly operation
}
}

(But really, equality is everywhere. Want to get the index of an object in an array? You need equality).

This blogpost takes you through a lot of options: Equatable (protocol can only be used as a generic constraint), NSObject protocol, etc.

It also shows the problem with creating your own implementation of func ==

struct Apple {
var price: Double = 0.99
}
struct Orange {
var price: Double = 0.99
}

and suddenly, Apple() == Orange() returns true. Ooops.

(And, of course, equality becomes costly to maintain if you have to write out every relevant property; it’s easy to update your protocol and forget to update your == function.)

My solution is to have a global MyProtocolID; every object I create gets its own unique ID, and now I have something I can compare.

This means using
myArray.firstIndex(where: {$0.objectID == wantedObject.objectID} )

instead of
myArray.firstIndex(of: wantedObject)

but that’s a small price to pay.