Skip to content

Re-entrant loadView / viewDidLoad #3753

Closed
@jleandroperez

Description

@jleandroperez
Contributor

Platform

iOS

Installed

Swift Package Manager

Version

8.21.0

Steps to Reproduce

  1. Setup Sentry with PerformanceTracking and a profilingRate of 0.5
  2. Launch the app

50% of the times we launch our app, Sentry's swizzled loadView method invokes the .view property of the relevant ViewController.

This ends up triggering two viewDidLoad invocations in our ViewController, and is causing duplication of UI objects (+ performance degradation).

Expected Result

No loadView / viewDidLoad duplication

Actual Result

Our main viewController is getting x2 viewDidLoad invocations. Please review the screenshots below:



Are you willing to submit a PR?

Of course, PR will be up shortly. Thank you =)

Activity

moved this to Waiting for: Product Owner in GitHub Issues with 👀 2on Mar 15, 2024
bjhomer

bjhomer commented on Mar 15, 2024

@bjhomer
Contributor

Specifically, the issue can be seen in the first screenshot, where loadViewIfNeeded is being called, and that is recursively calling into loadViewIfNeeded again before the view was fully loaded the first time.

brustolin

brustolin commented on Mar 18, 2024

@brustolin
Contributor

Hello @jleandroperez, thanks for reaching out.
I don't see the double viewDidLoad in your screenshots.
I couldn't reproduce it either.
Can you explain a little bit more about your view controller setup?

moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 2on Mar 18, 2024
bjhomer

bjhomer commented on Mar 19, 2024

@bjhomer
Contributor

Hi, I'm @jleandroperez's co-worker. Don't look for duplicate viewDidLoad; look for duplicate loadViewIfNeeded. The issue can be seen in the stack traces on the left side of the screenshot. Inside -[DOIMainContainerViewController setChildViewController:], we are accessing the .view of a view controller for the first time. This is triggering loadViewIfNeeded on the view controller that was passed in (as seen in frames 30-32). That's going down into some Sentry code (-[SentryUIApplication relevantViewControllerFromWindow:]) which eventually ends up calling .view on that same view controller that's already loading its view.

Since the view has not finished loading yet, .view is apparently still nil. So accessing the view results in it loading the view again (seen in frames 12-14 on the stack). After that view finishes loading, it will call viewDidLoad (as seen in frame 1). And then it will unwind back to frames 30-32, UIKit will finish loading the view, and then call viewDidLoad from there. This means that the view got loaded into memory twice.

The duplicate viewDidLoad is a problem, but the bigger problem is that the entire UI is being loaded twice. (In our case, this is happening near the root level of the entire app hierarchy, so loading the UI twice involves loading a bunch of other views and view controllers as well.)

moved this to Waiting for: Product Owner in GitHub Issues with 👀 2on Mar 19, 2024

13 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Done

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @bjhomer@jleandroperez@kahest@brustolin

      Issue actions

        Re-entrant loadView / viewDidLoad · Issue #3753 · getsentry/sentry-cocoa