• 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. 重写 ==

    参考资料:

  • 相关阅读:
    docker 使用 记录
    vagrant up 网络问题
    PHPSTORM去除警告波浪线的方法
    vagrant共享目录出现“mount:unknown filesystem type ‘vboxsf‘”错误解决方法(亲测可行)
    SVN比较本地相对于上一版本的修改
    Mysql on duplicate key update用法及优缺点
    win10中PHPstorm 里面Terminal 不能使用 esc键吗退出编辑模式吗
    在docker 上安装lnmp 环境
    经典算法题每日演练——第九题 优先队列
    经典算法题每日演练——第十二题 线段树
  • 原文地址:https://www.cnblogs.com/gaox97329498/p/12070350.html
Copyright © 2020-2023  润新知