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

Posted

技术标签:

【中文标题】对于 Watch Complication 和 Time Travel,getTimelineEntriesForComplication 经常被(太)调用【英文标题】:With a Watch Complication and Time Travel, getTimelineEntriesForComplication is called (too) often 【发布时间】:2016-07-23 10:57:06 【问题描述】:

从下面的数据来看,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?您是重新加载时间线还是延长时间线?您每次通话返回多少过去的时间线条目?您所说的“我目前正努力成为一个好公民并拨打发烧电话以重新生成我的并发症数据”是什么意思。您的数据源不是使用现有的静态模型,并且仅返回请求的时间线条目吗? (提供一些代码将有助于回答一些问题,并且可能仍然是必要的。) 【参考方案1】:

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

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

我相信这是一种优化,旨在优先考虑即将到来的时间线条目(相对于最近的过去条目)。

回到 watchOS 2.0.1,复杂功能服务器首先用未来的条目填充时间线,然后继续 backfill the timeline with past entries。当然,Apple 可能会选择批量处理过去的条目以优先考虑最近的条目而不是更远的条目,这当然是可以理解的。

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

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

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

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

这在 watchOS 3 中变得更加重要,当您是 not merely updating a complication 时,还会在后台更新您的应用程序。即使您现在仍需要支持 watchOS 2,您也应该设计如何获取数据和更新复杂功能,以了解 watchOS 3 如何完成对整个应用程序的更新。

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

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

这其实是多年以来的标准做法,常见于UITableViewDataSource,其中numberOfSectionsInTableViewmight be called several times之类的方法。

正如另一位发帖者所写,一个方法被调用的次数can change between different versions of the OS。

如果是错误怎么办?

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

关于时间旅行的无关注释

我注意到您想提供 4 天的未来时间旅行条目。这将超过时间旅行滑动窗口。

为了效率,你可以考虑latestTimeTravelDate

在构建您的时间线时,请勿在此日期之后创建任何条目。这样做是浪费时间,因为这些条目不会立即显示。

【讨论】:

谢谢!关于latestTimeTravelDate 的好提示 - 立即实施。这种行为似乎已经停止。无法判断这是我这边的错误还是 watchOS 决定不更新太多。从那以后,我尝试优化并发症日期条目的数量,并将更新之间的时间增加到每天 4 次左右。【参考方案2】:

我几乎可以肯定这实际上与我在 watchOS 应用中遇到的问题相同;我的代码正在生成从最近到最近排序的时间线条目数组,而复杂服务器希望条目按从最近到最近的顺序排列。

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

我的解决方法是将我的 getTimelineEntries(for:after:limit:withHandler:) 函数从 appending 条目更改为索引 0 处的 inserting。

【讨论】:

以上是关于对于 Watch Complication 和 Time Travel,getTimelineEntriesForComplication 经常被(太)调用的主要内容,如果未能解决你的问题,请参考以下文章

WatchKit Complication:从扩展委托获取复杂数据

AngularJS $watch 与 $watchCollection:性能哪个更好?

对于 Swift 中的 Apple Watch OS,如何在 WCSession 激活完成后运行函数?

离开 iPhone 时在 Apple Watch 上记录和保存锻炼?

computed 和 watch 区别

Vue中watch和computed的区别和应用场景