您当前的位置: 首页 >  swift

Swift中自定义类==比较方法未被调用的分析和解决

发布时间:2018-10-21 16:01:55 ,浏览量:0

在项目中自定义了2个类:A和B,其中A含有B的实例变量.

在这2个类中都定义了==比较方法,按照正常来说:比较A,必然比较B.因为需要比较A中类型为B的实例变量.

但实际运行中发现,两个字面上完全一样的A实例对象,比较竟然不相等!!!

在A的==方法中下断点,发现3个问题:

  1. 比较不相等是因为其中B实例变量的比较不相等
  2. B实例比较并没有调用B中的==比较方法
  3. 最为奇怪的是:在Xcode的lldb中手动输入同样的相等表达式,结果却是相等的!

首先将A和B中的==的方法比较一下,并没有什么值得特别注意的地方.

但是有一点,A在项目本身中,而B却在static lib中!!!

在B中的==方法是这样写的:

static func ==(lhs: HyDateRange, rhs: HyDateRange) -> Bool {
   if lhs.start == rhs.start,lhs.end == rhs.end{
        return true
    }
    return false
}

其中start和end都是Date类型.看出什么问题了么???

我可以负责任地说:就该方法实现本身来说,是没有任何问题的!只是该方法可见域错了!它必须要是public!!!

如果不是public,则不会被外界(App)调用!但在比较的时候的确调用了一个返回false的比较方法,那是什么呢?我们再来看一下类B的定义:

@objc(Objc_B)
public class B:NSObject,NSCopying,NSCoding{

}

可以看到,B派生自NSObject类,而NSObject类是遵守Equatable协议的,这意味着该类为你隐式生成了一个==方法,而你之前调用的就是这个方法,可想而知该方法默认比较的是两个实例的===(引用)比较,自然返回false!

那么A的==方法为什么不用写public限定?因为前面说了A是在项目里的,在同一项目中统统都可以访问到,所以不用写public前缀.

所以前两个问题的解决很简单,就是在B类的==方法前面加上public限定!

现在还有第三个问题:为毛调试里相同相等判断表达式的结果和App实际运行时的不一样???

这个本猫只有猜测:App运行时其==方法是编译时绑定(至少对于类的这个static方法来说是),而lldb调试时是即时绑定,此时lldb在运行时可以"看到"原本不能"看到"的非public==方法,所以判断结果是正确的.

以上纯属猜测,欢迎指正 ?

最后,感谢观赏 ?

关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    107766博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.2789s