The following code works when compiling for macOS:
print(NSMutableDictionary().isEqual(to: NSMutableDictionary()))
but produces a compiler error when compiling for iOS:
'NSMutableDictionary' is not convertible to '[AnyHashable : Any]'
NSDictionary.isEqual(to:)
has the same signature on macOS and iOS. Why does this happen? Can I use NSDictionary.isEqual(_:)
instead?
Well, that is strange.
Because:
-
On iOS, the compiler is using
-[NSDictionary isEqualToDictionary:]
. Its parameter is of typeNSDictionary
, which gets imported as[AnyHashable: Any]
. -
On macOS the compiler finds the
-isEqualTo:
method, added by a category onNSObject
by<Foundation/NSScriptWhoseTests.h
. Its parameter isnullable id
, which gets imported asAny?
.
That header is associated with Foundation’s AppleScript support, and thus isn’t present on iOS.
What’s weird is that the compiler chooses to use the category method. The dictionary method seems more specific. However, Swift’s overload resolution rules are both complex and not documented precisely, so it’s hard to say whether it’s right or wrong. If you want to ‘language lawyer’ that, I recommend that you bounce over to Swift Forums.
Yes. Well, it’s NSObject.isEqual(_:)
, but NSDictionary
overrides it with the right logic.
The whole -isEqualToXxx:
stuff always confused me. I’m not really sure why it exists. Sure, it’s slightly faster, but how much does that actually buy you?
Alternative you could use Swift’s ==
, because for NSObject subclasses that dispatches through -isEqual:
.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"