Swift Array.contains() 不调用 PFUser 子类的 Eequalable 函数



我有一个PFUser-MYUser类的子类,实现了Equatable函数,用于以这种方式比较对象ID:

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

但是当我调用Array.contains()方法时,它没有调用Equatable函数的此实现,这会导致不正确的结果。例如,这里:

let hasUser = self.selectedUsers.contains(currentUser)

如果selectedUsers数组包含不同的内存对象,但对象ID与currentUser中的对象ID相同,则hasUseralse。

有趣的是,Equatable函数实现在直接使用中被调用。此处:

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

==成功调用了运算符,hasUser对于不同的内存对象具有正确的值,但具有相同的objectId

是什么原因造成的?

更新。这是MYUser类:

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
}

我认为这是NSObject问题吗。

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)")

打印错误。

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)")

打印真实。


最后,通过添加-isEqual:,我修复了这个问题。

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)")

打印真实。


针对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)")

打印真实。

注意:不再需要==(left:right:)功能。

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)")

最新更新