skip to Main Content

I have two UITextField instances and upon update I need to figure out which one is updated, usually I’d use === to check reference identity, but accidentally put == instead and it worked. So I wonder if UITextField conforms to Equatable and what actually are involved in comparison?

To illustrate:

let textFieldA = UITextField()
let textFieldB = UITextField()

textFieldA.text = "A"
textFieldB.text = "B"

print("A.text", textFieldA.text)
print("B.text", textFieldB.text)
print("A == A:", textFieldA == textFieldA)
print("A == B:", textFieldA == textFieldB)
print("A === B:", textFieldA === textFieldB)

textFieldB.text = "A"

print("A.text", textFieldA.text)
print("B.text", textFieldB.text)
print("A == A:", textFieldA == textFieldA)
print("A == B:", textFieldA == textFieldB)
print("A === B:", textFieldA === textFieldB)

Output:

A.text Optional("A")
B.text Optional("B")
A == A: true
A == B: false
A === B: false
A.text Optional("A")
B.text Optional("A")
A == A: true
A == B: false
A === B: false

So == and === works the same regardless of whether their text are same or different, I wonder what is happening under the hood?

Thanks!

2

Answers


  1. UITextField extends UIControl -> UIView -> UIResponder -> NSObject which conforms to the NSObject protocol.

    NSObject conforms to Hashable which extends Equatable.

    Ultimately the Swift == operator is going to call the isEqual: method that UITextField inherits from NSObject. The default implementation of this is to simply compare the pointer.

    UITextField does not override isEqual: to compare the text property or any other property. So the end result is that == and === are effectively the same in this case.

    Use === when you only care about if the two references are to the same object. Don’t use == just because it gives the same result in this case. It’s possible that could change in some future update.

    Login or Signup to reply.
  2. UITextField is a subclass of NSObject, and NSObject conforms to Hashable, which means it also conforms to Equatable.

    NSObject.== is implemented by delegating to isEqual, and the default implementation of isEqual compares object identities. See the code in NSObject.swift in the swift-corelibs-foundation implementation,

    public static func ==(lhs: NSObject, rhs: NSObject) -> Bool {
        return lhs.isEqual(rhs)
    }
    
    open func isEqual(_ object: Any?) -> Bool {
        guard let obj = object as? NSObject else { return false }
        return obj === self
    }
    

    And frankly, that is the only reasonable implementation of NSObject.== I can think of.

    Evidently, UITextField did not override isEqual, and so comparing with == produces the same result as comparing with ===.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search