Skip to main content

CADisplayLink with NSRunLoopCommonModes not executed for every frame when tracking UIScrollView?



I am trying to execute a small piece of code on every single frame in a regular (non-OpenGL) iPhone app. The goal is to have a frame counter so that I can measure (rather than guess) where the slow points in the app are and fix them to create a better user experience.





What I've done so far is register a CADisplayLink for all modes (including tracking):







CADisplayLink *displayLink = [[CADisplayLink displayLinkWithTarget:self selector:@selector(frame)] retain];

[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];







The code that is executed looks like this (lastDraw is a NSDate* and count an int):







- (void) frame {

NSDate *newDate = [NSDate date];



if([newDate timeIntervalSinceDate:lastDraw] >= 1) {

label.text = [NSString stringWithFormat:@"%d FPS", count];



count = 0;

[lastDraw release];

lastDraw = [newDate retain];

}



count++;

}







The idea here is to get an update every one second as to how many frames were drawn in the past second.





This seems to work ok, but the numbers are definitely off when scrolling in a UIScrollView: If I just scroll like a normal person then the frame rates seem to make sense. However, if I scroll vigorously up and down then the displayed rate drops down to 1 or 2 fps, but clearly there are more frames drawn than just one every second.





When I change the frame method like such:







- (void) frame {

label.text = [NSString stringWithFormat:@"%f", displayLink.timestamp];

}







It becomes obvious that very few events are fired when I scroll.





I have read a lot of articles here and around the web that deal with UIScrollViews and NSRunLoopCommonModes vs NSDefaultRunLoopMode but haven't found someone describing my problem. The closest I found was in this question







Remember that if a CADisplayLink is unable to fire for a screen refresh (due to the main thread being busy doing things like drawing the previous frame) then it may skip it, as it won't have enough time to complete.







I can't seem to find any evidence for that in the official documentation , though, and hope that I am doing something wrong...





If it makes any difference the device in question is running iOS 4.3.3.


Comments

  1. What happens if you add your display link to UITrackingRunLoopMode in addition to NSRunLoopCommonModes?

    ReplyDelete

Post a Comment

Popular posts from this blog

Slow Android emulator

I have a 2.67 GHz Celeron processor, 1.21 GB of RAM on a x86 Windows XP Professional machine. My understanding is that the Android emulator should start fairly quickly on such a machine, but for me it does not. I have followed all instructions in setting up the IDE, SDKs, JDKs and such and have had some success in staring the emulator quickly but is very particulary. How can I, if possible, fix this problem?