Date.addingTimeInterval(_:) 和 Date.advanced(by:) 有什么区别?

5
基金会的Date结构提供了Date.addingTimeInterval(_:)Date.advanced(by:)这两个方法,它们在功能上似乎是相同的,但明显是不同的方法。它们实际上有什么区别还是最终相同的呢?
查看文档可知,advanced(by:)什么也没说,而addingTimeInterval(_:)只是说:

要添加的值,以秒为单位。

与NSDate进行比较时,advanced(by:)完全没有出现。情况变得更加复杂!
1个回答

10

.addingTimeInterval(_:) 是来自 ObjC NSDate 的长期存在的方法。 .advanced(by:) 存在是为了匹配 Swift 中的 Strideable 协议。Date 同样有一个 Stride 类型别名。

尽管如此,Date 实际上并不符合 Strideable 协议,这已经被讨论过并被普遍拒绝

可步进伪一致性(Strideable pseudo-conformance)似乎是作为Xcode 11.4的一个大型合并的一部分添加的,它位于名为Schedulers+Date的扩展中,该扩展似乎是Combine的一部分(Combine不是开源的)。我在论坛中没有看到任何关于它的讨论,除了一个注意事项指出它破坏了现有代码。更改说明:

// Date cannot conform to Strideable per rdar://35158274
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
 extension Date /* : Strideable */ {

我的直觉是,在Combine的某个地方,将Date回溯符合Strideable的标准。您可以通过简单地请求来获得相同的结果:
extension Date: Strideable {}

感觉Swift标准库团队认为Date不应该是可步进的(我同意这种推理,因为它会导致很多常见的日期错误),但苹果的其他团队想要它,并将钩子放入了stdlib中,但没有实现符合性。


如果我没记错的话,Date 在一些早期测试版中确实短暂地采用了 Strideable(为了支持 Combine 功能),但由于在 Swift 中,追溯性(时间上)符合性是 ABI 破坏性变化,所以它被放弃了。目前还没有支持指示特定 OS 发布中引入协议符合性的方法,但如果我没记错的话,这也是计划中的。 - Itai Ferber
我们不再有旧版Xcode测试版的访问权限,但我相信这是变更的一个简短后果:https://forums.swift.org/t/foundation-date-conforming-to-strideable-ios-13/33221 - Itai Ferber
这解释了很多问题,但这是否意味着这两种方法之间存在任何功能上的区别,或者 advanced(by:) 很可能在幕后调用了 addingTimeInterval(_:)?我猜想在几乎所有情况下都应该使用 addingTimeInterval(_:)。你有什么想法吗? - mredig
2
它们实际上都是使用 + 实现的。你使用哪个取决于个人口味。个人而言,我总是会使用 addingTimeInterval,因为这是传统名称,而且在我看来,date.advanced(by: 4)date + 4 都是可怕的语法。这里的“4”是什么?秒?毫秒?纳秒?如果我对 Cocoa 不是非常熟悉,我会期望 date + 4 添加 4 天(它就在那里说“date”!)。TimeInterval 被定义为始终是秒,因此当它说“addingTimeInterval”时,很清楚。在我看来,其他所有东西都是非常常见的错误来源。但是其他人可能有不同的看法。 - Rob Napier
这些是非常好的观点!我一定会记住这些并在以后继续努力。 :) - mredig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接