用于重试操作的抽象类。 其目的是提供一种简洁易用的方式来创建重试操作。 例如,如果您执行操作以获取某些网络资源,则该操作可能会失败,因为现在没有互联网连接。 但是,互联网可能很快就会恢复! 您可能希望等待几秒钟并重试请求,而不是通过告诉用户没有网络并且他应该重试来打扰用户。
重试操作类为您提供了一种轻松处理重试过程的方法。
注意:已取消的操作不会重试。
RetryingOperation
是一个抽象类。 为了使用它,您必须对其进行子类化。
通常,当子类化 Operation
时,如果要编写异步操作,您可以子类化 start()
、executing
、finished
和 asynchronous
,或者对于同步操作,只需子类化 main()
即可。
要正确地子类化 RetryingOperation
,您只需子类化 startBaseOperation()
和 asynchronous
。 在您的实现中,您负责启动您的操作,但您不必担心管理操作的 executing
和 finished
属性:它们由您管理。
当您的操作完成时,您必须调用 baseOperationEnded()
。 您传递给此方法的参数将决定是否应重试操作以及重试延迟。 即使操作完成是因为操作被取消,也必须调用该方法(即使在操作被取消的情况下重试参数被忽略)。 实际上,如果您的操作是同步的,则必须在 startBaseOperation()
返回之前调用该方法……
当您的操作正在等待重试时,您可以调用 retryNow()
或 retry(withHelpers:)
来绕过当前的重试助手,并立即重试或设置新的助手。 注意:如果在调用这些方法时,基本操作已在运行、从未启动或已完成,则不会执行任何操作,但会在日志中打印警告。
startBaseOperation()
和 cancelBaseOperation()
将从同一个私有的 GCD 队列中调用。 当您被调用时,不要对这些方法的线程方面做出任何其他假设。 另请注意,您可能没有正常工作的运行循环。 如果您正在编写异步操作,则您必须尽快离开该方法,就像您在覆盖 start()
时所做的那样。
用例:我正在使用一个框架,该框架提供了很好的操作。 我想使这些操作可重试,但我无法使它们继承自 RetryingOperation
,因为我不拥有它们。 我该怎么办?
一个解决方案是使用 RetryableOperationWrapper
。 有关更多信息,请参阅此类的文档。
此项目最初由 François Lamboley 在 happn 工作时创建。