Swift equality

最后更新: 2017-07-23

在程序开发中,我们时常需要来判断两个对象是否相等。在编程思想中,两个对象相等指的是在内存中的地址相同,也就是两个指针指向同一个地址。但是在日常理解中,只要两个对象的内容相同即表示想等,怎么处理这类问题才是此文所需要阐述的。

在iOS开发中,无论是OC还是Swift都有一定的方式来处理此问题,因此我们将从两种语言的角度来阐述.


Objective-C

在OC中,任何对象都继承与NSObject,NSObject定义了如下方法来比较两个对象是否相同,

- (BOOL)isEqual:(id)object;

image_1blmradl61vq679u1imvbetmm69.png-240.1kB

从官方解释中,我们可以获取到如下信息

  1. 如果两个对象相同,那么两个对象的 Hash值一定相同,反之
  2. 如果你想重写 isEqual:,同时你也要去重写 hash
    详细内容可以去参考:
  3. Equality
  4. 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重写 isEqualHash 的方式。但Swift是一门面向协议编程的语言,Swift也能够重载操作符,因此,我们可以采用更加便捷的方式来处理。

多说一句, Xcode提供playground对我们而言,简直就是神兵利器.

Class

  1. 重写 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
        }
    }
    
  2. 重写 ==

参考资料:

posted @ 2017-07-23 21:33  洒水先生  阅读(303)  评论(0编辑  收藏  举报