在项目中自定义了2个类:A和B,其中A含有B的实例变量.
在这2个类中都定义了==比较方法,按照正常来说:比较A,必然比较B.因为需要比较A中类型为B的实例变量.
但实际运行中发现,两个字面上完全一样的A实例对象,比较竟然不相等!!!
在A的==方法中下断点,发现3个问题:
- 比较不相等是因为其中B实例变量的比较不相等
- B实例比较并没有调用B中的==比较方法
- 最为奇怪的是:在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==方法,所以判断结果是正确的.
以上纯属猜测,欢迎指正 ?
最后,感谢观赏 ?