Overridden == function for Equatable type not called for custom class that subclasses NSCoding and NSObject

Crashalot picture Crashalot · May 7, 2016 · Viewed 8.7k times · Source

The FooBar class below has to override the == function of the Equatable type.

However, calling contains on an array of FooBar objects does not cause a breakpoint inside the custom == function to get invoked. Is it possible another == function is overriding this custom one?

Note: Because FooBar must subclass from NSCoding and NSObject, FooBar does not list Equatable as a protocol because it causes this error:

Redundant conformance of 'FooBar' to protocol 'Equatable'

func ==(lhs: FooBar, rhs: FooBar) -> Bool {
    return lhs.id == rhs.id
}

class FooBar: NSObject, NSCoding {
     // Class def
}

// Both serverFooBars and gFooBars are [FooBar]
let newFooBars = serverFooBars.filter { !gFooBars.contains($0) }

Answer

Blake Lockley picture Blake Lockley · May 7, 2016

Because your class inherits from NSObject you do not need to use the swift protocol Equatable instead you must override the NSObject method isEquals:

Swift 3.x and above

class FooBar: NSObject, NSCoding {
  override func isEqual(_ object: Any?) -> Bool {
    return id == (object as? FooBar)?.id
  }
}

(Thanks to Kamchatka)

Swift 2.x

class FooBar: NSObject, NSCoding {
  override func isEqual(object: AnyObject?) -> Bool {
    return id == (object as? FooBar)?.id
  }
}