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

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.