Swift equality
最后更新: 2017-07-23
在程序开发中,我们时常需要来判断两个对象是否相等。在编程思想中,两个对象相等指的是在内存中的地址相同,也就是两个指针指向同一个地址。但是在日常理解中,只要两个对象的内容相同即表示想等,怎么处理这类问题才是此文所需要阐述的。
在iOS开发中,无论是OC还是Swift都有一定的方式来处理此问题,因此我们将从两种语言的角度来阐述.
Objective-C
在OC中,任何对象都继承与NSObject
,NSObject定义了如下方法来比较两个对象是否相同,
- (BOOL)isEqual:(id)object;
从官方解释中,我们可以获取到如下信息
- 如果两个对象相同,那么两个对象的
Hash
值一定相同,反之- 如果你想重写
isEqual:
,同时你也要去重写hash
详细内容可以去参考:- Equality
- NSObject subclass in Swift: hash vs hashValue, isEqual vs ==
例子:
建立一个OC的工程,然后创建一个 Student
,因为学生的学号是唯一,因此我们创建一个sNo
属性表示学号, name
表示名称,就这么简单就可以了。(实际情况可能很复杂,但是思想基本不变话)
为了简单方便,我们做如下代码
Student *s1 = [[Student alloc] initWithNo:@"10" name:@"zhangsan"];
Student *s2 = [[Student alloc] initWithNo:@"10" name:@"zhangsan"];
BOOL isEqual = [s1 isEqual:s2]; // false
isEqual
比较两个对象的所指向的内存地址,明显不一致,因此为 false
因为同一个学号只能表示同一个人,因此,我们可以重写 Student
中的isEqual
方法
- (BOOL)isEqual:(Student *)object
{
if (!object) {
return NO;
}
if (![object isKindOfClass:[Student class]]) {
return NO;
}
return [[self identifier] isEqualToString:[object identifier]];
}
- (NSUInteger)hash
{
return [self identifier].hash;
}
// 抽离出来,更好扩展
- (NSString *)identifier
{
return self.sNo;
}
注意一点: 如果两个对象相同,那么他们的hash一定相同.
但是: hash相同,对象不一定相同, 可Google 散列冲突
Swift
Swift中存在 Class(类)
和 Struct(结构体)
, 如果一个类继承 NSObject
,我们可以采用上面OC重写 isEqual
与 Hash
的方式。但Swift是一门面向协议编程的语言,Swift也能够重载操作符
,因此,我们可以采用更加便捷的方式来处理。
多说一句, Xcode提供playground
对我们而言,简直就是神兵利器.
Class
-
重写
isEqual
&Hash
// Override Hash and isEqual class Student : NSObject { var sID : String init(sID : String) { self.sID = sID } override func isEqual(_ object: Any?) -> Bool { guard let obj = object as? Student else { return false} return self.identifier.hashValue == obj.identifier.hashValue } override var hash: Int { return self.identifier.hashValue } var identifier : String { return self.sID } }
-
重写
==
参考资料: