Ios 在应用程序启动时预加载ViewController

Ios 在应用程序启动时预加载ViewController,ios,swift,uiviewcontroller,Ios,Swift,Uiviewcontroller,我有一个很重的UIViewController,它在viewDidLoad中加载多个图像,因此只在第一次访问控制器时调用一次。 加载它需要5-10秒,我想减少,从应用程序启动时的某个地方预加载它 我已经完成了我的研究,并尝试访问控制器的view属性,以便在AppDelegate的didFinishLaunchingWithOptions方法中加载它,它实际上确实调用了viewDidLoad,但当我打开控制器本身时,viewDidLoad会再次调用,所有图像也会再次加载 当前代码示例如下所示: f

我有一个很重的UIViewController,它在viewDidLoad中加载多个图像,因此只在第一次访问控制器时调用一次。 加载它需要5-10秒,我想减少,从应用程序启动时的某个地方预加载它

我已经完成了我的研究,并尝试访问控制器的view属性,以便在AppDelegate的didFinishLaunchingWithOptions方法中加载它,它实际上确实调用了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,使其在打开时不需要加载太多?它保存的数据是完全静态的,因此任何解决方案都适用。

我建议从控制器中提取所有加载逻辑。创建一个DataLoader类或结构,用于加载和存储加载的数据

在AppDelegate中实例化一个数据加载器,并指示它加载与视图控制器分离的数据。然后将此实例传递给控制器,以便控制器可以访问加载程序中的数据

您可能需要实现一些状态跟踪,以确保当您向加载程序请求数据时,它将开始加载,或者在加载过程中等待


另外,您还可以在后台队列中实现加载,这样就不会阻塞UI。

我建议从控制器中提取所有加载逻辑。创建一个DataLoader类或结构,用于加载和存储加载的数据

在AppDelegate中实例化一个数据加载器,并指示它加载与视图控制器分离的数据。然后将此实例传递给控制器,以便控制器可以访问加载程序中的数据

您可能需要实现一些状态跟踪,以确保当您向加载程序请求数据时,它将开始加载,或者在加载过程中等待


另外,您还可以在后台队列中实现加载,这样就不会阻塞UI。

尽管您的解决方案无法帮助您实现更快的加载,而且您必须使繁重的工作异步:

您解释的问题是,当您实例化EviewController时,它会创建一个新的视图控制器,该控制器与您稍后将看到的完全不同。因此,你必须得到它。一种方法是从appDelegate中的主窗口访问它:

let controller = window?.rootViewController as? modeDescriptionViewController
然后,您可以强制它加载它的视图,这是根本不推荐的

Controller.loadView()
然后它会自动调用viewDidLoad


提示:如果窗口未加载,您可以在其上调用makeKeyAndVisible。

尽管您的解决方案无法帮助您实现更快的加载,并且您必须使繁重的工作异步:

您解释的问题是,当您实例化EviewController时,它会创建一个新的视图控制器,该控制器与您稍后将看到的完全不同。因此,你必须得到它。一种方法是从appDelegate中的主窗口访问它:

let controller = window?.rootViewController as? modeDescriptionViewController
然后,您可以强制它加载它的视图,这是根本不推荐的

Controller.loadView()
然后它会自动调用viewDidLoad


提示:如果窗口未加载,您可以调用makeKeyAndVisible。wvteijlingen的答案应该是,将繁重的业务逻辑从控制器提取到专用类中是最佳解决方案。但是,如果重构很复杂,那么您可以遵循下面描述的方法

一旦方法退出,您在didFinishLaunchingWithOptions中创建的控制器实例将丢失,因此其视图和视图加载的内容将被丢弃。如果要重用该实例,可以将其存储到AppDelegate的属性中:

var modeDescriptionViewController:UIViewController! func应用程序uApplication:UIApplication,didFinishLaunchingWithOptions launchOptions:[UIApplication.launchOptions键:任意]?->布尔{ let storyboardname:Main,bundle:nil modeDescriptionViewController=storyboard.InstanceEviewController标识符:modeDescriptionViewController //LoadViewIf需要更干净 modeDescriptionViewController.LoadViewIf需要 返回真值 }
从现在开始,您可以在需要时访问视图控制器:UIApplication.shared.delegate as!AppDelegate.modeDescriptionViewController

wvteijlingen的答案应该是可行的,将繁重的业务逻辑从控制器提取到专用类中是最佳解决方案。但是,如果重构很复杂,那么您可以遵循下面描述的方法

一旦方法退出,您在didFinishLaunchingWithOptions中创建的控制器实例将丢失,因此其视图和视图加载的内容将被丢弃。如果要重用该实例,可以将其存储到AppDelegate的属性中:

变量 modeDescriptionViewController:UIViewController! func应用程序uApplication:UIApplication,didFinishLaunchingWithOptions launchOptions:[UIApplication.launchOptions键:任意]?->布尔{ let storyboardname:Main,bundle:nil modeDescriptionViewController=storyboard.InstanceEviewController标识符:modeDescriptionViewController //LoadViewIf需要更干净 modeDescriptionViewController.LoadViewIf需要 返回真值 } 从现在开始,您可以在需要时访问视图控制器:UIApplication.shared.delegate as!AppDelegate.modeDescriptionViewController