NSDate isEqual 的问题
既然swift开源了,你可以看swift源码里Foundation的相关对象是如何实现的:
apple/swift
简单来说就是一个浮点数比较的问题.
当你获取一个Date对象的timeIntervalSince1970属性时,返回的实际上是self.timeIntervalSinceReferenceDate + Date.timeIntervalBetween1970AndReferenceDate, 其中 Date.timeIntervalBetween1970AndReferenceDate 为常量978307200.0。timeIntervalSinceReferenceDate这个getter方法对应的是内部的_time 存储属性,也就是说timeIntervalSince1970 这个getter方法是通过浮点数加法计算出来的。
然后你用获取到的timeIntervalSince1970这个属性去构造一个新的Date对象,调用的是init(timeIntervalSince1970: TimeInterval) 这个构造函数。这个构造函数内部调用了self.init(timeIntervalSinceReferenceDate: timeIntervalSince1970 - Date.timeIntervalBetween1970AndReferenceDate),也就是说把timeIntervalSince1970 - Date.timeIntervalBetween1970AndReferenceDate 这个浮点数减法表达式的值赋给了新的Date对象的_time属性。
Date是如何实现Comparable使得我们能比较两个Date对象呢?它返回的是lhs.timeIntervalSinceReferenceDate == rhs.timeIntervalSinceReferenceDate,那么其实上就是比较两个Date对象的_time属性。而我们通过上述步骤已经看到,第二个Date对象的_time属性是通过第一个Date对象的_time属性加上一个浮点常量后再减去同一个浮点常量----而这样并不能保证我们一定能得到和原来相同的值。
【NSDate isEqual 的问题】 我们不妨可以做一个实验,在playground里输入如下代码:
let x = 527613976.798304
let y = x + 978307200.0
print(y - 978307200.0 == x)
你可以确认返回的是true还是false : )
那么最后该如何正确的比较两个Date对象是否相等呢?我建议是只要他们的时间间隔的绝对值落在某个范围内就判断相等即可,当然不同的场景可以有不同的方案,这个要靠你自己来判断了。
■网友
建议在category中重写NSDate的对象等同性,即-isEqualsToDate:方法和-isEqual:方法,以及-hash方法,当时间在某个范围之内时即表示相等。这样可以避免浮点运算的问题,想怎么搞就怎么搞。
推荐阅读
- 江苏■江苏交控坚持问题导向、瞄准职工需求——找准“病灶”当好“产改先行官”
- 贵州在建骨干水源工程达到465座有效解决工程性区域性缺水问题
- 四川眉山瓦屋山景区就游客投诉、停车难等问题公开道歉
- 杭州已整改城市道路无障碍环境问题12467处
- 互联网怎样解决“家政服务上门速度慢”的问题
- 中东问题|
- 中国网汽车|购车2个多月、仅行驶8000多公里 宝骏730遭遇7处问题
- |沛县深入开展教育领域突出问题专项整改
- 交换机,路由器经常性的死机咋办
- 微博目前已经支持文本,图片,位置分享,为啥没有语音和视频呢微博的pm肯定想过这两种微博形态,但迟迟不做的原因到底是啥。是语音和视频不符合产
