Предварительная загрузка ViewController при запуске приложения - PullRequest
0 голосов
/ 31 января 2019

У меня тяжелый UIViewController, который загружает несколько изображений в viewDidLoad (поэтому он вызывается один раз, только при первом доступе к контроллеру).Для его загрузки требуется 5-10 секунд, который я хочу уменьшить, предварительно загрузив его откуда-то при запуске приложения.

Я провел свое исследование и попытался получить доступ к атрибуту view контроллера, чтобы он загрузился в didFinishLaunchingWithOptions метод AppDelegate, и это действительно произошло (был вызван viewDidLoad), нокогда я включаю сам контроллер, снова вызывается viewDidLoad и все изображения загружаются снова.

Ниже приведен пример текущего кода:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: "modeDescriptionViewController")
    let _ = vc.view  // viewDidLoad is called here

    return true
}

Как я могу предварительно загрузить огромный UIViewController, чтобы при открытии он не загружался так много?Данные, которые он хранит, полностью статичны, поэтому подойдет любое решение.

Ответы [ 3 ]

0 голосов
/ 31 января 2019

Хотя ваше решение не поможет вам добиться более быстрой загрузки, и вы ДОЛЖНЫ выполнять тяжелые работы async:

Ваша объясненная проблема заключается в том, что когда вы instantiateViewController создаете новый контроллер представления, которыйполностью отличается от того, что вы увидите позже.Поэтому вместо этого вы должны получить это.Один из способов сделать это - получить к нему доступ из основного window в appDelegate:

let controller = window?.rootViewController as? modeDescriptionViewController

Затем вы можете принудительно загрузить его для просмотра (не рекомендуется)

Controller.loadView()

А затем он автоматически вызывает viewDidLoad

Совет: если window не загружен, вы можете вызвать makeKeyAndVisible() для него.

0 голосов
/ 01 февраля 2019

Ответ wvteijlingen должен быть верным, извлечение тяжелой (бизнес) логики из контроллера в выделенный класс является оптимальным решением.Однако если рефакторинг будет сложным, то вы можете следовать подходу, описанному ниже.


Экземпляр контроллера, который вы создаете в didFinishLaunchingWithOptions, теряется при выходе из метода, поэтому его представление и содержимое, загружаемоевид отбрасывается.Если вы хотите повторно использовать этот экземпляр, вы можете сохранить его в свойстве AppDelegate:

var modeDescriptionViewController: UIViewController!

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    modeDescriptionViewController = storyboard.instantiateViewController(withIdentifier: "modeDescriptionViewController")
    // loadViewIfNeeded() is cleaner
    modeDescriptionViewController.loadViewIfNeeded()
    return true
}

И с этого момента вы можете получить доступ к контроллеру представления при необходимости: UIApplication.shared.delegate as! AppDelegate).modeDescriptionViewController.

0 голосов
/ 31 января 2019

Я бы предложил извлечь всю логику загрузки из контроллера.Создайте DataLoader класс (или структуру), который выполняет загрузку и сохраняет загруженные данные.

Создайте DataLoader в вашем AppDelegate и дайте ему указание загрузить данные, отделенные от контроллера представления.Затем передайте этот экземпляр контроллеру, чтобы контроллер мог получить доступ к данным из загрузчика.

Возможно, вам потребуется реализовать некоторое отслеживание состояния, чтобы убедиться, что при запросе данных у загрузчика он будет либоначать загрузку или подождать, если загрузка уже выполняется.

Плюс, вы также можете реализовать загрузку в фоновой очереди, чтобы она не блокировала пользовательский интерфейс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...