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?
ios objective-c xcode breakpoints uiactivityindicatorview
|
show 1 more comment
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?
ios objective-c xcode breakpoints uiactivityindicatorview
Can you post your code?
– Augustine P A
May 4 '13 at 8:14
where u have called "stop animating" in u r code?
– Nithinbemitk
May 4 '13 at 9:14
1
What do you mean, pause the app?
– David H
May 4 '13 at 12:14
1
I press the debugger pause button in Xcode to "Pause program execution". That's the tool tip that comes up when you hover over the debugger pause button. If I pause the application I expect all threads in the application to stop but the animation still keeps going which lead me to believe the activity indicator doesn't run on the main thread. The code is trivial - (IBAction)buttonPressed:(id)sender { [self.activityIndicator startAnimating]; } I'm just doing something to start the activity indicator and wondering why it isn't stopping when I hit pause in the debugger.
– Gerard
May 5 '13 at 18:31
Five years later I am wondering the same thing. In my case, I do asleep(timeInterval)
on the main thread. The Activity Indicator just keeps spinning. But for example the blinking text cursor (e.g. in aUITextView
when editing) does indeed freeze.
– Nikolay Suvandzhiev
Jan 5 '18 at 12:37
|
show 1 more comment
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?
ios objective-c xcode breakpoints uiactivityindicatorview
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?
ios objective-c xcode breakpoints uiactivityindicatorview
ios objective-c xcode breakpoints uiactivityindicatorview
edited May 6 '13 at 2:04
Gerard
asked May 4 '13 at 2:22
GerardGerard
54939
54939
Can you post your code?
– Augustine P A
May 4 '13 at 8:14
where u have called "stop animating" in u r code?
– Nithinbemitk
May 4 '13 at 9:14
1
What do you mean, pause the app?
– David H
May 4 '13 at 12:14
1
I press the debugger pause button in Xcode to "Pause program execution". That's the tool tip that comes up when you hover over the debugger pause button. If I pause the application I expect all threads in the application to stop but the animation still keeps going which lead me to believe the activity indicator doesn't run on the main thread. The code is trivial - (IBAction)buttonPressed:(id)sender { [self.activityIndicator startAnimating]; } I'm just doing something to start the activity indicator and wondering why it isn't stopping when I hit pause in the debugger.
– Gerard
May 5 '13 at 18:31
Five years later I am wondering the same thing. In my case, I do asleep(timeInterval)
on the main thread. The Activity Indicator just keeps spinning. But for example the blinking text cursor (e.g. in aUITextView
when editing) does indeed freeze.
– Nikolay Suvandzhiev
Jan 5 '18 at 12:37
|
show 1 more comment
Can you post your code?
– Augustine P A
May 4 '13 at 8:14
where u have called "stop animating" in u r code?
– Nithinbemitk
May 4 '13 at 9:14
1
What do you mean, pause the app?
– David H
May 4 '13 at 12:14
1
I press the debugger pause button in Xcode to "Pause program execution". That's the tool tip that comes up when you hover over the debugger pause button. If I pause the application I expect all threads in the application to stop but the animation still keeps going which lead me to believe the activity indicator doesn't run on the main thread. The code is trivial - (IBAction)buttonPressed:(id)sender { [self.activityIndicator startAnimating]; } I'm just doing something to start the activity indicator and wondering why it isn't stopping when I hit pause in the debugger.
– Gerard
May 5 '13 at 18:31
Five years later I am wondering the same thing. In my case, I do asleep(timeInterval)
on the main thread. The Activity Indicator just keeps spinning. But for example the blinking text cursor (e.g. in aUITextView
when editing) does indeed freeze.
– Nikolay Suvandzhiev
Jan 5 '18 at 12:37
Can you post your code?
– Augustine P A
May 4 '13 at 8:14
Can you post your code?
– Augustine P A
May 4 '13 at 8:14
where u have called "stop animating" in u r code?
– Nithinbemitk
May 4 '13 at 9:14
where u have called "stop animating" in u r code?
– Nithinbemitk
May 4 '13 at 9:14
1
1
What do you mean, pause the app?
– David H
May 4 '13 at 12:14
What do you mean, pause the app?
– David H
May 4 '13 at 12:14
1
1
I press the debugger pause button in Xcode to "Pause program execution". That's the tool tip that comes up when you hover over the debugger pause button. If I pause the application I expect all threads in the application to stop but the animation still keeps going which lead me to believe the activity indicator doesn't run on the main thread. The code is trivial - (IBAction)buttonPressed:(id)sender { [self.activityIndicator startAnimating]; } I'm just doing something to start the activity indicator and wondering why it isn't stopping when I hit pause in the debugger.
– Gerard
May 5 '13 at 18:31
I press the debugger pause button in Xcode to "Pause program execution". That's the tool tip that comes up when you hover over the debugger pause button. If I pause the application I expect all threads in the application to stop but the animation still keeps going which lead me to believe the activity indicator doesn't run on the main thread. The code is trivial - (IBAction)buttonPressed:(id)sender { [self.activityIndicator startAnimating]; } I'm just doing something to start the activity indicator and wondering why it isn't stopping when I hit pause in the debugger.
– Gerard
May 5 '13 at 18:31
Five years later I am wondering the same thing. In my case, I do a
sleep(timeInterval)
on the main thread. The Activity Indicator just keeps spinning. But for example the blinking text cursor (e.g. in a UITextView
when editing) does indeed freeze.– Nikolay Suvandzhiev
Jan 5 '18 at 12:37
Five years later I am wondering the same thing. In my case, I do a
sleep(timeInterval)
on the main thread. The Activity Indicator just keeps spinning. But for example the blinking text cursor (e.g. in a UITextView
when editing) does indeed freeze.– Nikolay Suvandzhiev
Jan 5 '18 at 12:37
|
show 1 more comment
2 Answers
2
active
oldest
votes
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
This answer is correct. You can see this in the metal strace logs too - backboardd is the one sending the render commands. Sorry for the incorrect answer.
– TheLivingForce
Jan 19 at 3:41
Yes, I think so. Thank you both of you guys! @rob mayoff, how did you find out?
– blyabtroi
Jan 20 at 19:39
I figured it out by experimentation, based on things I have learned from watching many WWDC videos and general research.
– rob mayoff
Jan 20 at 19:41
add a comment |
Addressing blyabtroi as his comment is recent...
tl;dr: CoreAnimation elements give ongoing render instructions to the GPU, CoreGraphics elements don't and need to reissue instructions every iteration of the run loop.
Longer explanation:
All onscreen rendering is done via the GPU. However, the GPU does rendering based on CPU render instructions and a pool of CPU-manipulated graphics memory (this is a traditional graphics pipeline).
"Pause program execution" in the debugger pauses all CPU threads, but it doesn't pause any GPU processes. Anything that has a standing command issued to the GPU (basically all CAAnimations such as CAKeyframeAnimation), instructs the GPU to render their content to their section of the screen without stopping. Anything whose commands are issued via a CPU thread (as all CoreGraphics content must strictly do) is paused.
This can be illustrated via the Metal System Trace instrument and a small sample seen below (run in viewDidLoad of a single-view application with a text field and an activity indicator):
[NSTimer scheduledTimerWithTimeInterval:5.0 repeats:NO block:^(NSTimer * _Nonnull timer) {
dispatch_async(dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval: 1000000000];
});
}];
As you can see, the CPU is reporting no activity during this time - it's currently stuck in the long-lasting sleepForTimeInterval. The GPU, however, continues on unimpeded, running its full graphics pipeline, complete with the animation commands given by CoreAnimation.
Thank you. I agree that GPU is involved. But why these lines are stop working when I pause program execution: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ for (int i=0; i<1000000000; i++) { NSLog(@"in background %d", i); } });
– blyabtroi
Jan 18 at 7:37
I see. Do you mean the closure is paused (i.e. the NSLogs get paused when you hit the pause button)?
– TheLivingForce
Jan 18 at 8:01
Yes, exactly. Why?
– blyabtroi
Jan 18 at 10:50
Sorry, I was confused with something else. Let me know if the revised answer clears things up.
– TheLivingForce
Jan 19 at 2:28
This answer is wrong. It's not the GPU that keeps the animation going. It's the window server (calledbackboardd
on iOS and in the simulator).
– rob mayoff
Jan 19 at 3:33
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f16369956%2fwhy-does-an-activity-indicator-still-spin-when-an-app-is-paused%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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
This answer is correct. You can see this in the metal strace logs too - backboardd is the one sending the render commands. Sorry for the incorrect answer.
– TheLivingForce
Jan 19 at 3:41
Yes, I think so. Thank you both of you guys! @rob mayoff, how did you find out?
– blyabtroi
Jan 20 at 19:39
I figured it out by experimentation, based on things I have learned from watching many WWDC videos and general research.
– rob mayoff
Jan 20 at 19:41
add a comment |
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
This answer is correct. You can see this in the metal strace logs too - backboardd is the one sending the render commands. Sorry for the incorrect answer.
– TheLivingForce
Jan 19 at 3:41
Yes, I think so. Thank you both of you guys! @rob mayoff, how did you find out?
– blyabtroi
Jan 20 at 19:39
I figured it out by experimentation, based on things I have learned from watching many WWDC videos and general research.
– rob mayoff
Jan 20 at 19:41
add a comment |
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
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
answered Jan 19 at 3:15
rob mayoffrob mayoff
292k41591641
292k41591641
This answer is correct. You can see this in the metal strace logs too - backboardd is the one sending the render commands. Sorry for the incorrect answer.
– TheLivingForce
Jan 19 at 3:41
Yes, I think so. Thank you both of you guys! @rob mayoff, how did you find out?
– blyabtroi
Jan 20 at 19:39
I figured it out by experimentation, based on things I have learned from watching many WWDC videos and general research.
– rob mayoff
Jan 20 at 19:41
add a comment |
This answer is correct. You can see this in the metal strace logs too - backboardd is the one sending the render commands. Sorry for the incorrect answer.
– TheLivingForce
Jan 19 at 3:41
Yes, I think so. Thank you both of you guys! @rob mayoff, how did you find out?
– blyabtroi
Jan 20 at 19:39
I figured it out by experimentation, based on things I have learned from watching many WWDC videos and general research.
– rob mayoff
Jan 20 at 19:41
This answer is correct. You can see this in the metal strace logs too - backboardd is the one sending the render commands. Sorry for the incorrect answer.
– TheLivingForce
Jan 19 at 3:41
This answer is correct. You can see this in the metal strace logs too - backboardd is the one sending the render commands. Sorry for the incorrect answer.
– TheLivingForce
Jan 19 at 3:41
Yes, I think so. Thank you both of you guys! @rob mayoff, how did you find out?
– blyabtroi
Jan 20 at 19:39
Yes, I think so. Thank you both of you guys! @rob mayoff, how did you find out?
– blyabtroi
Jan 20 at 19:39
I figured it out by experimentation, based on things I have learned from watching many WWDC videos and general research.
– rob mayoff
Jan 20 at 19:41
I figured it out by experimentation, based on things I have learned from watching many WWDC videos and general research.
– rob mayoff
Jan 20 at 19:41
add a comment |
Addressing blyabtroi as his comment is recent...
tl;dr: CoreAnimation elements give ongoing render instructions to the GPU, CoreGraphics elements don't and need to reissue instructions every iteration of the run loop.
Longer explanation:
All onscreen rendering is done via the GPU. However, the GPU does rendering based on CPU render instructions and a pool of CPU-manipulated graphics memory (this is a traditional graphics pipeline).
"Pause program execution" in the debugger pauses all CPU threads, but it doesn't pause any GPU processes. Anything that has a standing command issued to the GPU (basically all CAAnimations such as CAKeyframeAnimation), instructs the GPU to render their content to their section of the screen without stopping. Anything whose commands are issued via a CPU thread (as all CoreGraphics content must strictly do) is paused.
This can be illustrated via the Metal System Trace instrument and a small sample seen below (run in viewDidLoad of a single-view application with a text field and an activity indicator):
[NSTimer scheduledTimerWithTimeInterval:5.0 repeats:NO block:^(NSTimer * _Nonnull timer) {
dispatch_async(dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval: 1000000000];
});
}];
As you can see, the CPU is reporting no activity during this time - it's currently stuck in the long-lasting sleepForTimeInterval. The GPU, however, continues on unimpeded, running its full graphics pipeline, complete with the animation commands given by CoreAnimation.
Thank you. I agree that GPU is involved. But why these lines are stop working when I pause program execution: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ for (int i=0; i<1000000000; i++) { NSLog(@"in background %d", i); } });
– blyabtroi
Jan 18 at 7:37
I see. Do you mean the closure is paused (i.e. the NSLogs get paused when you hit the pause button)?
– TheLivingForce
Jan 18 at 8:01
Yes, exactly. Why?
– blyabtroi
Jan 18 at 10:50
Sorry, I was confused with something else. Let me know if the revised answer clears things up.
– TheLivingForce
Jan 19 at 2:28
This answer is wrong. It's not the GPU that keeps the animation going. It's the window server (calledbackboardd
on iOS and in the simulator).
– rob mayoff
Jan 19 at 3:33
add a comment |
Addressing blyabtroi as his comment is recent...
tl;dr: CoreAnimation elements give ongoing render instructions to the GPU, CoreGraphics elements don't and need to reissue instructions every iteration of the run loop.
Longer explanation:
All onscreen rendering is done via the GPU. However, the GPU does rendering based on CPU render instructions and a pool of CPU-manipulated graphics memory (this is a traditional graphics pipeline).
"Pause program execution" in the debugger pauses all CPU threads, but it doesn't pause any GPU processes. Anything that has a standing command issued to the GPU (basically all CAAnimations such as CAKeyframeAnimation), instructs the GPU to render their content to their section of the screen without stopping. Anything whose commands are issued via a CPU thread (as all CoreGraphics content must strictly do) is paused.
This can be illustrated via the Metal System Trace instrument and a small sample seen below (run in viewDidLoad of a single-view application with a text field and an activity indicator):
[NSTimer scheduledTimerWithTimeInterval:5.0 repeats:NO block:^(NSTimer * _Nonnull timer) {
dispatch_async(dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval: 1000000000];
});
}];
As you can see, the CPU is reporting no activity during this time - it's currently stuck in the long-lasting sleepForTimeInterval. The GPU, however, continues on unimpeded, running its full graphics pipeline, complete with the animation commands given by CoreAnimation.
Thank you. I agree that GPU is involved. But why these lines are stop working when I pause program execution: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ for (int i=0; i<1000000000; i++) { NSLog(@"in background %d", i); } });
– blyabtroi
Jan 18 at 7:37
I see. Do you mean the closure is paused (i.e. the NSLogs get paused when you hit the pause button)?
– TheLivingForce
Jan 18 at 8:01
Yes, exactly. Why?
– blyabtroi
Jan 18 at 10:50
Sorry, I was confused with something else. Let me know if the revised answer clears things up.
– TheLivingForce
Jan 19 at 2:28
This answer is wrong. It's not the GPU that keeps the animation going. It's the window server (calledbackboardd
on iOS and in the simulator).
– rob mayoff
Jan 19 at 3:33
add a comment |
Addressing blyabtroi as his comment is recent...
tl;dr: CoreAnimation elements give ongoing render instructions to the GPU, CoreGraphics elements don't and need to reissue instructions every iteration of the run loop.
Longer explanation:
All onscreen rendering is done via the GPU. However, the GPU does rendering based on CPU render instructions and a pool of CPU-manipulated graphics memory (this is a traditional graphics pipeline).
"Pause program execution" in the debugger pauses all CPU threads, but it doesn't pause any GPU processes. Anything that has a standing command issued to the GPU (basically all CAAnimations such as CAKeyframeAnimation), instructs the GPU to render their content to their section of the screen without stopping. Anything whose commands are issued via a CPU thread (as all CoreGraphics content must strictly do) is paused.
This can be illustrated via the Metal System Trace instrument and a small sample seen below (run in viewDidLoad of a single-view application with a text field and an activity indicator):
[NSTimer scheduledTimerWithTimeInterval:5.0 repeats:NO block:^(NSTimer * _Nonnull timer) {
dispatch_async(dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval: 1000000000];
});
}];
As you can see, the CPU is reporting no activity during this time - it's currently stuck in the long-lasting sleepForTimeInterval. The GPU, however, continues on unimpeded, running its full graphics pipeline, complete with the animation commands given by CoreAnimation.
Addressing blyabtroi as his comment is recent...
tl;dr: CoreAnimation elements give ongoing render instructions to the GPU, CoreGraphics elements don't and need to reissue instructions every iteration of the run loop.
Longer explanation:
All onscreen rendering is done via the GPU. However, the GPU does rendering based on CPU render instructions and a pool of CPU-manipulated graphics memory (this is a traditional graphics pipeline).
"Pause program execution" in the debugger pauses all CPU threads, but it doesn't pause any GPU processes. Anything that has a standing command issued to the GPU (basically all CAAnimations such as CAKeyframeAnimation), instructs the GPU to render their content to their section of the screen without stopping. Anything whose commands are issued via a CPU thread (as all CoreGraphics content must strictly do) is paused.
This can be illustrated via the Metal System Trace instrument and a small sample seen below (run in viewDidLoad of a single-view application with a text field and an activity indicator):
[NSTimer scheduledTimerWithTimeInterval:5.0 repeats:NO block:^(NSTimer * _Nonnull timer) {
dispatch_async(dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval: 1000000000];
});
}];
As you can see, the CPU is reporting no activity during this time - it's currently stuck in the long-lasting sleepForTimeInterval. The GPU, however, continues on unimpeded, running its full graphics pipeline, complete with the animation commands given by CoreAnimation.
edited Jan 19 at 2:27
answered Jan 17 at 21:09
TheLivingForceTheLivingForce
180416
180416
Thank you. I agree that GPU is involved. But why these lines are stop working when I pause program execution: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ for (int i=0; i<1000000000; i++) { NSLog(@"in background %d", i); } });
– blyabtroi
Jan 18 at 7:37
I see. Do you mean the closure is paused (i.e. the NSLogs get paused when you hit the pause button)?
– TheLivingForce
Jan 18 at 8:01
Yes, exactly. Why?
– blyabtroi
Jan 18 at 10:50
Sorry, I was confused with something else. Let me know if the revised answer clears things up.
– TheLivingForce
Jan 19 at 2:28
This answer is wrong. It's not the GPU that keeps the animation going. It's the window server (calledbackboardd
on iOS and in the simulator).
– rob mayoff
Jan 19 at 3:33
add a comment |
Thank you. I agree that GPU is involved. But why these lines are stop working when I pause program execution: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ for (int i=0; i<1000000000; i++) { NSLog(@"in background %d", i); } });
– blyabtroi
Jan 18 at 7:37
I see. Do you mean the closure is paused (i.e. the NSLogs get paused when you hit the pause button)?
– TheLivingForce
Jan 18 at 8:01
Yes, exactly. Why?
– blyabtroi
Jan 18 at 10:50
Sorry, I was confused with something else. Let me know if the revised answer clears things up.
– TheLivingForce
Jan 19 at 2:28
This answer is wrong. It's not the GPU that keeps the animation going. It's the window server (calledbackboardd
on iOS and in the simulator).
– rob mayoff
Jan 19 at 3:33
Thank you. I agree that GPU is involved. But why these lines are stop working when I pause program execution: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ for (int i=0; i<1000000000; i++) { NSLog(@"in background %d", i); } });
– blyabtroi
Jan 18 at 7:37
Thank you. I agree that GPU is involved. But why these lines are stop working when I pause program execution: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ for (int i=0; i<1000000000; i++) { NSLog(@"in background %d", i); } });
– blyabtroi
Jan 18 at 7:37
I see. Do you mean the closure is paused (i.e. the NSLogs get paused when you hit the pause button)?
– TheLivingForce
Jan 18 at 8:01
I see. Do you mean the closure is paused (i.e. the NSLogs get paused when you hit the pause button)?
– TheLivingForce
Jan 18 at 8:01
Yes, exactly. Why?
– blyabtroi
Jan 18 at 10:50
Yes, exactly. Why?
– blyabtroi
Jan 18 at 10:50
Sorry, I was confused with something else. Let me know if the revised answer clears things up.
– TheLivingForce
Jan 19 at 2:28
Sorry, I was confused with something else. Let me know if the revised answer clears things up.
– TheLivingForce
Jan 19 at 2:28
This answer is wrong. It's not the GPU that keeps the animation going. It's the window server (called
backboardd
on iOS and in the simulator).– rob mayoff
Jan 19 at 3:33
This answer is wrong. It's not the GPU that keeps the animation going. It's the window server (called
backboardd
on iOS and in the simulator).– rob mayoff
Jan 19 at 3:33
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f16369956%2fwhy-does-an-activity-indicator-still-spin-when-an-app-is-paused%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Can you post your code?
– Augustine P A
May 4 '13 at 8:14
where u have called "stop animating" in u r code?
– Nithinbemitk
May 4 '13 at 9:14
1
What do you mean, pause the app?
– David H
May 4 '13 at 12:14
1
I press the debugger pause button in Xcode to "Pause program execution". That's the tool tip that comes up when you hover over the debugger pause button. If I pause the application I expect all threads in the application to stop but the animation still keeps going which lead me to believe the activity indicator doesn't run on the main thread. The code is trivial - (IBAction)buttonPressed:(id)sender { [self.activityIndicator startAnimating]; } I'm just doing something to start the activity indicator and wondering why it isn't stopping when I hit pause in the debugger.
– Gerard
May 5 '13 at 18:31
Five years later I am wondering the same thing. In my case, I do a
sleep(timeInterval)
on the main thread. The Activity Indicator just keeps spinning. But for example the blinking text cursor (e.g. in aUITextView
when editing) does indeed freeze.– Nikolay Suvandzhiev
Jan 5 '18 at 12:37