sahandnayebaziz sahandnayebaziz - 7 months ago 24
Swift Question

Is it possible to perform a deep property comparison dynamically in Swift at runtime?

Let's say we have two instances of

UILabel
that, to us, are equivalent:

let label1 = UILabel()
label1.text = "Hello world"

let label2 = UILabel()
label2.text = "Hello world"


Let's say the two instances are in an array of type
[UIView]
:

let views: [UIView] = [label1, label2]


Is there any way to perform an equality check that would find these two instances of
UIView
to be equivalent without knowing which type they are ahead of time (and therefore which common properties to compare on)?

(Any way to use the fact that these instances are both have a
dynamicType
of
UILabel
and dynamically run through the key/value properties of the
UILabel
class and compare each value that can be compared?)

What's happening:

label1 == label2 // false
views[0] == views[1] // false


What's desired:

areTheSame(label1, label2) // true
areTheSame(views[0], views[1]) // true


We are looking for a way to compare two separate instances, so we can't use
===
.

Answer

Swift has no reflection so this is not possible. We can't even get a list of attributes.

Also note that for many types there is no definition of equality. Even comparing two floating point values is a problem.

Exactly for this reason we have the Equatable protocol. If you want to compare types, define equality on them. That equality can then go as deep as needed, without the need for any dynamic (unsafe) behavior.

Just to explain another corner case, for example, on UILabel there are some properties that you definitely don't want to compare, namely things like nextResponder or superview. Trying to deep compare those properties would actually end up in a loop. Usually it's not possible to compare two objects for equality without knowing exactly what should and what should not be compared.