Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does an activity indicator still spin when an app is paused?

I created a simple application with just a button and an activity indicator. When I press the button I have the activity indicator start animating. In Xcode 4.6 iPhone 6.1 Simulator I see the activity indicator spinning. When I pause the application I sometimes land in libsystem_kernel.dylib`mach_msg_trap. This appears to be on the com.apple.main-thread which is thread 1. Shouldn't pausing the app this way block the main thread and so stop the activity indicator from spinning? It doesn't appear to.

Update: This article ( http://www.dragthing.com/blog/2009/07/how-to-make-your-iphone-app-launch-faster/ ) says "As I discovered, the UIActivityIndicatorView animation is run on a thread by the system – that means, even though my application is blocked inside its initialisation code while it starts up, the spinner will still be spinning." Is it possible the UIActivityIndicatorView is animated off the main thread?

like image 209
Gerard Avatar asked May 04 '13 02:05

Gerard


1 Answers

A UIActivityIndicator draws its image using a UIImageView subview, and animates the image by attaching a CAKeyframeAnimation to the image view's layer. You can see the arrangement by printing the view hierarchy:

(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>>

Your app doesn't run these animations. Your app sends these animations to the window server and the window server runs them. That's why they keep running when your app is paused. All threads in your app are paused, but the window server is not paused.

You can prove this by stopping the simulator's window server. It is called backboardd. From the command line, run this command:

killall -STOP backboardd

You'll see that the activity indicator stops spinning. Then run this command to resume:

killall -CONT backboardd
like image 60
rob mayoff Avatar answered Sep 26 '22 01:09

rob mayoff