Calling presentViewController:animated:completion: from within tableView:didSelectRowAtIndexPath: is very slow

Originator:michaelab1
Number:rdar://19563577 Date Originated:22 January 2015
Status:Open Resolved:
Product:iOS SDK Product Version:iOS 8.1
Classification:Performance Reproducible:Always
 
Summary:
In a UITableViewController subclass, if you call presentViewController:animated:completion: from within your implementation of tableView:didSelectRowAtIndexPath: it can take a very long time (sometimes several seconds) to present the view controller.

If you push the view controller onto the Navigation Controller stack, there is no delay. Similarly, if the call to presentViewController:animated:completion: is made from within a dispatch_async block on the main thread, there is no delay.

I have provided an example Xcode project which demos the problem. In the example, the delay is not huge, but the same situation in a more complex app can cause a delay of several seconds.

Steps to Reproduce:
Open the attached example project (in TableViewDelayBug.zip) in Xcode and run the app.

The segmented control in the master view lets you choose between 3 ways of showing the detail view controller:
1. Push - calls pushViewController:animated:, and is instant.
2. Present - calls presentViewController:animated:completion: and has a noticeable delay.
3. Pres Async - calls presentViewController:animated:completion: from within a dispatch_async block on the main thread and is also instant.

The relevant code is all in MasterViewController.m in the implementation of tableView:didSelectRowAtIndexPath: at line 51.

Expected Results:
The detail view controller should appear instantly, regardless of whether it is pushed onto the navigation stack or presented modally. It should not be necessary to present modally from within a dispatch_async block in order to achieve an instant presentation.

Actual Results:
If the detail view controller is presented modally (without the workaround of a dispatch_async block) there is a noticeable delay before it appears.

Version:
iOS 8.1 (simulator or device)

Notes:


Configuration:
iPhone 6 (simulator or device)

Attachments:
'TableViewDelayBug.zip' was successfully uploaded.

Dropbox link to attachment: https://dl.dropboxusercontent.com/u/1020204/TableViewDelayBug.zip

Comments

Can you check the status w/ Apple? I confirmed it still is present in iOS 9.2.

By henrytkirk at March 22, 2016, 4:56 p.m. (reply...)

Video demonstration

Here's a video demonstration: http://youtu.be/In_u7wJOSH0 As you can see sometimes it presents the view controller/action sheet/activity sheet properly, other times it hangs indefinitely until you tap somewhere on the screen or shake the phone.

By tamas.zahola at June 11, 2015, 1:20 p.m. (reply...)

Sample project

Here's a sample project demonstrating the issue: https://github.com/tzahola/present-bug

By tamas.zahola at June 11, 2015, 1:06 p.m. (reply...)

Same issue here

I had the exact same issue today with iOS 8.3 (12F70). I've found that it is somehow related to the application's event loop. If nothing happens on the screen (no animation, no UI state changes) and the app receives no user input (tap, swipe, etc.) you can produce arbitrarily long delays between the presentViewController:animated:completion: call and the actual appearance of the view controller.

Steps to reproduce:

  1. Set your UITableViewCell's selectionStyle to UITableViewCellSelectionStyleNone, so that the cell's background change won't "trigger" the run loop
  2. Call presentViewController:animated:completion: from tableView:didSelectRowAtIndexPath:
  3. Wait

Now, 4 out of 10 cases, the view controller won't be presented until you provide some event to the app. For example, tapping the screen triggers the presentation to happen. Even shaking the device triggers it! Also, you can trigger it by dispatching an empty block to the main queue:

        [self presentViewController:viewController animated:YES completion:nil];
        dispatch_async(dispatch_get_main_queue(), ^{}); // this will trigger the presentViewController: to be executed properly

Pretty funny indeed :D

By tamas.zahola at June 11, 2015, 12:35 p.m. (reply...)

Screen recording to demo the problem

Was asked by Apple to provide a screen recording to demonstrate the problem as they have been unable to reproduce. Here is the link for the screen recording I sent them:

https://dl.dropboxusercontent.com/u/1020204/TableViewDelayBug.mov

By michaelab1 at March 11, 2015, 5:28 p.m. (reply...)

Continues in iOS 8.3 beta 2

Was asked by Apple to verify the bug continues in iOS 8.3 beta 2. I confirmed that it does.

By michaelab1 at Feb. 27, 2015, 8:58 p.m. (reply...)

Example project

https://dl.dropboxusercontent.com/u/1020204/TableViewDelayBug.zip

By michaelab1 at Jan. 22, 2015, 3:22 p.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!