Swift Array.contains () does not call the equivalent function of the PFUser subclass

I have a subclass of the PFUser class - MYUser with an implementation of the Equableable function to compare objectIds this way:

func ==(left: MYUser, right: MYUser) -> Bool { return left.objectId == right.objectId } 

But when I call the Array.contains () method, it does not call this implementation of the Equableable function, which leads to incorrect results. For example, here:

 let hasUser = self.selectedUsers.contains(currentUser) 

hasUser becomes false if the selectedUsers array contains a different memory object, but with the same object as in currentUser .

Interestingly, the implementation of the Equalable function is called in direct use. Here:

 var hasUser = false for itUser in self.selectedUsers { if itUser == currentUser { hasUser = true break } } 
Operator

== was called and hasUser has the correct values ​​for different memory objects, but with the same objectId

What could be the reason for this?

UPDATE Here is the MYUser class:

 class MYUser: PFUser { // MARK: - Parse Object @NSManaged var avatarFile: PFFile? @NSManaged var fullName: String? // MARK: - PFSubclassing Methods (through PFUser) override class func initialize() { struct Static { static var onceToken : dispatch_once_t = 0; } dispatch_once(&Static.onceToken) { self.registerSubclass() } } } func ==(left: MYUser, right: MYUser) -> Bool { return left.objectId == right.objectId } 
+5
source share
1 answer

I think this is an NSObject problem.

 class MYUserNSObject: NSObject { dynamic var fullName: String init(fullName: String) { self.fullName = fullName super.init() } } func ==(left: MYUserNSObject, right: MYUserNSObject) -> Bool { return left.fullName == right.fullName } let objectUsers = [MYUserNSObject(fullName: "a"), MYUserNSObject(fullName: "b")] let objectResult = objectUsers.contains(MYUserNSObject(fullName: "a")) print("\(result)") 

Prints false.

 class MYUserSwift: Equatable { var fullName: String init(fullName: String) { self.fullName = fullName } } func ==(left: MYUserSwift, right: MYUserSwift) -> Bool { return left.fullName == right.fullName } let swiftUsers = [MYUserSwift(fullName: "a"), MYUserSwift(fullName: "b")] let swiftResult = swiftUsers.contains(MYUserSwift(fullName: "a")) print("\(swiftResult)") 

Prints true.


Finally, adding -isEqual: I fixed it.

 class MYUserNSObject: NSObject { dynamic var fullName: String init(fullName: String) { self.fullName = fullName super.init() } override func isEqual(object: AnyObject?) -> Bool { guard let user = object as? MYUserNSObject else { return false } return self == user } } func ==(left: MYUserNSObject, right: MYUserNSObject) -> Bool { return left.fullName == right.fullName } let objectUsers = [MYUserNSObject(fullName: "a"), MYUserNSObject(fullName: "b")] let objectResult = objectUsers.contains(MYUserNSObject(fullName: "a")) print("\(objectResult)") 

Prints true.


Updated for Swift 4.0

 class MYUserNSObject: NSObject { @objc var fullName: String init(fullName: String) { self.fullName = fullName super.init() } override func isEqual(_ object: Any?) -> Bool { guard let user = object as? MYUserNSObject else { return false } return self.fullName == user.fullName } } let objectUsers = [MYUserNSObject(fullName: "a"), MYUserNSObject(fullName: "b")] let objectResult = objectUsers.contains(MYUserNSObject(fullName: "a")) print("\(objectResult)") 

Prints true.

Note: the function ==(left:right:) no longer required.

 let success = MYUserNSObject(fullName: "a") == objectUsers[0] print("success should be true: \(success)") let failure = MYUserNSObject(fullName: "a") == objectUsers[1] print("failure should be false: \(failure)") 
+9
source

Source: https://habr.com/ru/post/1239740/


All Articles