Swift Array.contains() 没有调用 PFUser 子类的 Equatable 函数
Swift Array.contains() doesn't call Equatable function of PFUser subclass
我有一个 PFUser 的子class - MYUser class 实现 Equatable 以这种方式比较 objectId 的函数:
func ==(left: MYUser, right: MYUser) -> Bool {
return left.objectId == right.objectId
}
但是当我调用 Array.contains() 方法时,它不会调用 Equatable 函数的这个实现,这会导致不正确的结果。例如,这里:
let hasUser = self.selectedUsers.contains(currentUser)
hasUser 变为 false 如果 selectedUsers 数组包含不同的内存对象但具有相同的 objectId如 currentUser.
有趣的是,直接使用调用了Equatable函数实现。这里:
var hasUser = false
for itUser in self.selectedUsers {
if itUser == currentUser {
hasUser = true
break
}
}
== 运算符被成功调用并且 hasUser 具有不同内存对象的正确值但具有相同的 objectId
可能是什么原因造成的?
更新。
这是我的用户 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
}
我认为这是一个 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)")
我有一个 PFUser 的子class - MYUser class 实现 Equatable 以这种方式比较 objectId 的函数:
func ==(left: MYUser, right: MYUser) -> Bool {
return left.objectId == right.objectId
}
但是当我调用 Array.contains() 方法时,它不会调用 Equatable 函数的这个实现,这会导致不正确的结果。例如,这里:
let hasUser = self.selectedUsers.contains(currentUser)
hasUser 变为 false 如果 selectedUsers 数组包含不同的内存对象但具有相同的 objectId如 currentUser.
有趣的是,直接使用调用了Equatable函数实现。这里:
var hasUser = false
for itUser in self.selectedUsers {
if itUser == currentUser {
hasUser = true
break
}
}
== 运算符被成功调用并且 hasUser 具有不同内存对象的正确值但具有相同的 objectId
可能是什么原因造成的?
更新。 这是我的用户 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
}
我认为这是一个 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)")