本文首发于图拉鼎的博客 I'M TUALATRIX,少数派经授权转载,仅对排版和内容略作调整。 


最近,iOS 13.2 频繁「杀」后台 App 的事情可以说是让全球的 iPhone 用户都很抓狂,大家纷纷在吐槽「bugOS」的同时,也在想是不是个别 App 不遵守规则,导致后台 App 频繁被退出。

我在前几天做过一个初步观察,说微信被退出的几率相当高,有些 App 则不太被退出。经朋友提醒,我发现 iOS 日志里有很多关于微信的 Wakeup 记录。那么,什么是 Wakeup?微信被退出后台会是过多 Wake 引起的吗?本文就针对这个问题进行一番探究。

初步观察

10 月 30 日,我在社交网络上发布了一个 初步观察,提出在我的 iOS 系统上,微信被退出的现象比较频繁,之后名为 @Er1cT4n9 的用户提醒了我说是 微信滥用 Wakeup 导致的这一现象。

我在 iOS 系统设置的「隐私 - 分析与改进 - 分析数据」选项中,确实找到了类似的日志。当时我望文生义,以为 Wakeup 指的就是应用在后台被唤醒,认为是微信频繁进行后台唤醒操作,才被 iOS 系统频繁「杀」掉。

我就这样得出了初步结论,想着等微信更新应该会解决这个问题。

进一步观察

往后几天,我特别注意观察了一下,发现不仅是微信,其它的 App 也会频繁被「杀」掉,只是程度不一样罢了。或者说,之前用着不太会被退出后台的 App,程度也相应增加了,可见 iOS 13.2 确实存在问题。对于这个现象,名为 Michael Tsai 的用户还整理了一份他对于社交网络上对于 iOS 13.2 「杀后台」现象的 言论汇总

这些现象告诉我,Wakeup 不是我想象中的 Wakeup,被退出后台的原因没那么简单,于是决定深入研究一下。

什么是 Wakeup?

那么 iOS 日志记录里的 Wakeup 是什么?难道不是字面意思上的「唤醒」吗?确实不是。

iOS 日志里记录的 Wakeup,不是 App 使用意义上的「唤醒」,而是线程级别的「唤醒」。这要如何去理解?对此我根据自己的理解进行了补充解释:

App 使用意义上的唤醒

一个放入后台的 App,当它想要更新地理位置或刷新消息时,它需要被唤醒才能做这些事情,于是它在被放入后台前,会和系统进行一些约定,比如「我是打车 App,我需要不断更新地理位置,所以你要常常唤醒我。」然后系统就会去唤醒它了。

通常 iOS App 被放入后台后,只能在有限的条件下被系统唤醒,而不能随意地自主唤醒进行操作。当我们不想要 App 被后台唤醒后,主动「杀」掉它基本上就可以达到目的了。

App 线程唤醒

一个 App,不管在前台或是后台,在进行具体的任务时,大多都需要用到多线程的模式,比如:为了不阻塞 UI,用一个线程下载内容,下载完成后切换到主线程去更新 UI。这个过程,就是一次 Wakeup。

关于「线程唤醒」的详细解释,可以看 Technical Note TN2151 的 这篇文章,我将相关解释的原文内容引用在这里:

The exception subtype WAKEUPS indicates that threads in the process are being woken up too many times per second, which forces the CPU to wake up very often and consumes battery life.

Typically, this is caused by thread-to-thread communication (generally using peformSelector:onThread: or dispatch_async) that is unwittingly happening far more often than it should be. Because the sort of communication that triggers this exception is happening so frequently, there will usually be multiple background threads with very similar Backtraces - indicating where the communication is originating.

从原文中可以明确得知,Wakeup 就是线程与线程的通讯,当发生异常情况,不管是 App 代码或系统层面,频繁地进行线程唤醒会占用 CPU 资源以及消耗电量。

应用频繁被「杀」的原因猜测

了解到什么是 Wakeup 后,我们基本上可以得出一个结论:微信等其它 App,频繁被退出,确实不能简单地归结于这些 App 在后台尝试唤醒自己太频繁而被系统杀掉。毕竟系统日志里也写明了 Acton taken 为 none。

也就是说,iOS 系统虽然记录了线程级别的 Wakeup 操作比较频繁,但是也没有因此就直接采取「杀」掉 App 的动作,App 在后台被退出是后续发生的事情。

根本原因还是 iOS 13.2 有系统级的 Bug,原本一些合法地让 App 进入后台后保持一段时间活跃状态的这个机制出了 Bug,导致了凡是用到这个机制的 App,都存在不同程度的被频繁退出的可能。

当然也不能因此就否认有些 App 会采用除系统合法机制之外的让自己保持活跃状态的各种 Trick。众所周知,iOS 13 在隐私和权限方面进一步严格了起来,也许 iOS 13 在处理这些 Trick 的时候,没能处理完美,导致了应用频繁被退出后台的现象发生。

结论

Wakeup 调用不是微信等 App 被退出的主动原因,而是一个触发了 iOS 13.2 中存在的问题或 Bug 后的现象。更深层和具体的原因,也许只有开发商和 Apple 一起去 Debug,才能找到了。希望解决问题后的 iOS 13.3 能够早日到来。

最后,有不少人反馈微信已经通过热更新解决了在后台频繁被退出的问题,我在测试之后也确实感受到微信能在后台待得更久了。

我的猜测是微信通过检测 iOS 13.2 版本,做了些 Workaround 绕过了系统的问题,也可能是专门针对 iOS 13.2 做了新的解决方案。

但是 iOS 13.2「杀后台」的现象并没有到此就解决了,还有很多其它的 App 存在这个问题。毕竟这是系统级的问题,连 Safari 都会被 iOS 13.2 频繁退出。还是期待 Apple 能够早日彻底解决这个问题吧。

> 下载少数派 客户端、关注 少数派公众号 ,了解更多 iOS 资讯  🆒

> 特惠、好用的硬件产品,尽在 少数派 sspai 官方店铺 🛒