对于 Watch Complication 和 Time Travel,getTimelineEntriesForComplication 被(太)经常调用

With a Watch Complication and Time Travel, getTimelineEntriesForComplication is called (too) often

根据下面的数据,ClockKit 会生成一次未来 CLKComplicationTimelineEntry 项,但对于过去的时间点,会调用 24 次!这是为什么?

更多详情:

我注意到我的 Apple Watch 并发症出现了奇怪的行为。

它支持时间旅行 -- 我提供过去 1 天和未来 4 天的数据。我目前正在努力成为一个好公民,减少调用来重新生成我的并发症数据。

为了了解某些调用的频率,我在 getTimelineEntries(for:before:limit:withHandler:)getTimelineEntries(for:after:limit:withHandler:) 中放置了一个简单的 print 输出 before/after 参数.

当我在模拟器中启动 App/Complication 时,我得到以下输出:

generate future timeline entries (after date:2016-07-23 10:33:31 +0000)
generate past timeline entries (before date:2016-07-23 10:33:31 +0000)
generate past timeline entries (before date:2016-07-23 09:33:31 +0000)
generate past timeline entries (before date:2016-07-23 08:33:31 +0000)
generate past timeline entries (before date:2016-07-23 07:33:31 +0000)
generate past timeline entries (before date:2016-07-23 06:33:31 +0000)
generate past timeline entries (before date:2016-07-23 05:33:31 +0000)
generate past timeline entries (before date:2016-07-23 04:33:31 +0000)
generate past timeline entries (before date:2016-07-23 03:33:31 +0000)
generate past timeline entries (before date:2016-07-23 02:33:31 +0000)
generate past timeline entries (before date:2016-07-23 01:33:31 +0000)
generate past timeline entries (before date:2016-07-23 00:33:31 +0000)
generate past timeline entries (before date:2016-07-22 23:33:31 +0000)
generate past timeline entries (before date:2016-07-22 22:33:31 +0000)
generate past timeline entries (before date:2016-07-22 21:33:31 +0000)
generate past timeline entries (before date:2016-07-22 20:33:31 +0000)
generate past timeline entries (before date:2016-07-22 19:33:31 +0000)
generate past timeline entries (before date:2016-07-22 18:33:31 +0000)
generate past timeline entries (before date:2016-07-22 17:33:31 +0000)
generate past timeline entries (before date:2016-07-22 16:33:31 +0000)
generate past timeline entries (before date:2016-07-22 15:33:31 +0000)
generate past timeline entries (before date:2016-07-22 14:33:31 +0000)
generate past timeline entries (before date:2016-07-22 13:33:31 +0000)
generate past timeline entries (before date:2016-07-22 12:33:31 +0000)
generate past timeline entries (before date:2016-07-22 11:33:31 +0000)

没有规定你的数据源方法只会被调用一次。您只需要准备好处理请求。

为什么它处理过去条目的方式与处理未来条目的方式不同?

我认为这是一项优化,旨在优先考虑即将到来的时间线条目(超过最近的过去条目)。

回到 watchOS 2.0.1,并发症服务器首先用未来的条目填充时间线,然后再继续 。这当然是可以理解的,Apple 可能会选择对过去的条目进行批处理,以优先考虑较新的条目而不是较远的条目。

虽然从那时起 Apple 确实调整了其代码,但可能在当前版本的 watchOS 中继续应用相同级别的关注和细节。

如果我要完成一项昂贵的手术怎么办?

如果您要做的不仅仅是简单地使用手头现有的复杂数据,并且您的数据检索与系统发出的特定请求相关联,您应该重构该代码以将其移出该方法。

一般来说,您希望手头有预取数据,可以直接将其转换为时间线条目。

当您 时,这在 watchOS 3 中变得更加重要,而且还会在后台更新您的应用程序。即使您现在仍然需要支持 watchOS 2,您也应该设计如何获取数据和更新复杂功能,以考虑 watchOS 3 如何完成更新您的整个应用程序。

为什么它多次调用我的数据源方法?

Apple 使用多种技术来优化复杂服务器(或操作系统的其他部分)的工作方式。您所能做的就是相信系统已经过调整以减少其内存和能源使用,并且它这样做是有充分理由的。

这实际上已经成为多年的标准做法,并且在 UITableViewDataSource 中很常见,其中像 numberOfSectionsInTableView .

这样的方法

正如另一位发帖人所写,方法被调用的次数

如果是bug怎么办?

它可能按预期工作,但如果您认为这是一个错误,您可以创建一个最小的示例项目并提交 bug report to Apple

一篇关于时间旅行的无关笔记

我注意到你想提供 4 天的未来时间旅行条目。这样会超过滑动的时间旅行window.

为了效率起见,你可以考虑latestTimeTravelDate:

When constructing your timeline, do not create any entries after this date. Doing so is a waste of time because those entries will not be displayed right away.

我几乎可以肯定这实际上是我在 watchOS 应用程序中遇到的同一个问题;我的代码正在生成一个时间线条目数组,从 最近到最近 排序,而 Complication 服务器想要条目从 最近到最近 排序].

并发症服务器因此使我生成的第一个条目以外的所有条目都无效,并在该条目之前立即请求更多更新。

我的修复是将我的 getTimelineEntries(for:after:limit:withHandler:) 函数从 appending 条目更改为 inserting 在索引 0.