12

我创建了一个简单的应用程序,只有一个按钮和一个活动指示器。当我按下按钮时,活动指示器开始动画。在 Xcode 4.6 iPhone 6.1 Simulator 中,我看到活动指示器在旋转。当我暂停应用程序时,我有时会进入 libsystem_kernel.dylib`mach_msg_trap。这似乎在线程 1 的 com.apple.main-thread 上。不应该以这种方式暂停应用程序会阻塞主线程,从而阻止活动指示器旋转吗?它似乎没有。

更新:这篇文章(http://www.dragthing.com/blog/2009/07/how-to-make-your-iphone-app-launch-faster/)说“正如我发现的那样,UIActivityIndi​​catorView 动画在系统的一个线程——这意味着,即使我的应用程序在启动时被阻塞在其初始化代码中,微调器仍然会旋转。” UIActivityIndi​​catorView 是否有可能在主线程上设置动画?

4

1 回答 1

11

AUIActivityIndicator使用子视图绘制其图像,并通过将 a 附加到图像视图的图层来为图像设置UIImageView动画。CAKeyframeAnimation您可以通过打印视图层次结构来查看排列:

(lldb) po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]
<UIWindow: 0x7fd778808c00; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x6000013b9ef0>; layer = <UIWindowLayer: 0x600001dcd400>>
   | <UIView: 0x7fd778d036f0; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x600001dc5bc0>>
   |    | <UIActivityIndicatorView: 0x7fd778d00280; frame = (177 323; 0 0); opaque = NO; autoresize = RM+BM; tintColor = UIExtendedGrayColorSpace 0 0.45; layer = <CALayer: 0x600001dc5a80>>
   |    |    | <UIImageView: 0x7fd778d06680; frame = (-10 -10; 20 20); opaque = NO;
                 userInteractionEnabled = NO; animations = {
                   contents=<CAKeyframeAnimation: 0x600001dc5f40>;
                   contentsMultiplyColor=<CAKeyframeAnimation: 0x600001dc5fa0>;
                 }; layer = <CALayer: 0x600001dc5ae0>>

您的应用不会运行这些动画。您的应用程序将这些动画发送到窗口服务器,然后窗口服务器运行它们。这就是为什么当您的应用程序暂停时它们会继续运行。应用程序中的所有线程都已暂停,但窗口服务器并未暂停。

您可以通过停止模拟器的窗口服务器来证明这一点。它被称为backboardd。从命令行运行以下命令:

killall -STOP backboardd

您会看到活动指示器停止旋转。然后运行此命令以恢复:

killall -CONT backboardd
于 2019-01-19T03:15:11.117 回答