[英]func == from equatable protocol does not work for custom object, swift
My goal is to show a user list of history logins ( such as username ) if there are any. 我的目标是显示历史登录的用户列表(例如用户名)(如果有)。 In order to do that, I am doing
为了做到这一点,我正在做
1. Create an custom object named User like below
class User: NSObject
{
var login: String
init(login: String)
{
self.login = login
}
required init(coder aDecoder: NSCoder) {
login = aDecoder.decodeObjectForKey("login") as! String
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(login, forKey: "login")
}
}
// This conform to make sure that I compare the `login` of 2 Users
func ==(lhs: User, rhs: User) -> Bool
{
return lhs.login == rhs.login
}
At UserManager, Im doing save
and retrieve
an User
. 在UserManager,我正在
save
并retrieve
User
。 Before saving, I'm doing a check if the the list of history logins contains a User
, I wont add it in, otherwise. 在保存之前,我正在检查历史记录登录列表是否包含
User
,我不会添加它,否则。
class UserManager : NSObject
{
static let sharedInstance = UserManager()
var userDefaults = NSUserDefaults.standardUserDefaults()
func saveUser(user:User)
{
var users = retrieveAllUsers()
// Check before adding
if !(users.contains(user))
{
users.append(user)
}
let encodedData = NSKeyedArchiver.archivedDataWithRootObject(users)
userDefaults.setObject(encodedData, forKey: "users")
userDefaults.synchronize()
}
func retrieveAllUsers() -> [User]
{
guard let data = userDefaults.objectForKey("users") as? NSData else
{
return [User]()
}
let users = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! [User]
// Testing purpose
for user in users
{
print(user.login)
}
return users
}
}
At first time trying, I do 在第一次尝试时,我做到了
UserManager.sharedInstance.saveUser(User(login: "1234"))
Now it saves the first login. 现在它保存了第一次登录。 At second time, I also do
第二次,我也这样做
UserManager.sharedInstance.saveUser(User(login: "1234"))
UserManager still adds the second login into nsuserdefault
. UserManager仍然将第二次登录添加到
nsuserdefault
。 That means the function contains
fails and it leads to 这意味着该函数
contains
失败并导致
func ==(lhs: User, rhs: User) -> Bool
{
return lhs.login == rhs.login
}
does not work properly. 不能正常工作。
Does anyone know why or have any ideas about this. 有谁知道为什么或有任何想法。
The problem is that User derives from NSObject. 问题是User派生自NSObject。 This means that (as you rightly say) your
==
implementation is never being consulted. 这意味着(正如你所说)你的
==
实现永远不会被咨询。 Swift's behavior is different for objects that derive from NSObject; 对于从NSObject派生的对象,Swift的行为是不同的; it does things the Objective-C way.
它以Objective-C的方式做事。 To implement equatability on an object that derives from NSObject, override
isEqual:
. 要在从NSObject派生的对象上实现可公平性,请覆盖
isEqual:
. That is what makes an NSObject-derived object equatable in a custom way, in both Objective-C and Swift. 这就是使得NSObject派生的对象在Objective-C和Swift中以自定义方式相同的原因。
Just paste this code right into your User class declaration, and contains
will start working as you wish: 只需将此代码粘贴到您的User类声明中,并且
contains
将按您的意愿开始工作:
override func isEqual(object: AnyObject?) -> Bool {
if let other = object as? User {
if other.login == self.login {
return true
}
}
return false
}
As @matt already said, the problem is about equality. 正如@matt所说,问题在于平等。
Look 看
var users = [User]()
users.append(User(login: "1234"))
users.contains(User(login: "1234")) // false
Look again 再看一遍
var users = [User]()
let user = User(login: "1234")
users.append(user)
users.contains(user) // true <---- THIS HAS CHANGED
The contains function is NOT using the logic you defined here contains函数不使用您在此处定义的逻辑
func ==(lhs: User, rhs: User) -> Bool {
return lhs.login == rhs.login
}
Infact it is simply comparing the memory addresses of the objects. 实际上,它只是比较对象的内存地址。
You can solve the issue passing your own logic to contains
, just replace this 您可以解决将您自己的逻辑传递给
contains
,只需替换它即可
if !(users.contains(user)) {
users.append(user)
}
with this 有了这个
if !(users.contains { $0.login == user.login }) {
users.append(user)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.