代码之家  ›  专栏  ›  技术社区  ›  pomo_mondreganto

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

  •  1
  • pomo_mondreganto  · 技术社区  · 5 年前

    UIViewController ,它在中加载多个图像 viewDidLoad (因此只在第一次控制器访问时调用一次)。

    我已经做了研究,并尝试访问 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 回复  |  直到 5 年前
        1
  •  3
  •   Rengers    5 年前

    我建议从控制器中提取所有加载逻辑。创建一个 DataLoader

    举例说明 数据加载器 在AppDelegate中,并指示它加载与视图控制器解耦的数据。然后将此实例传递给控制器,以便控制器可以访问加载程序中的数据。

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

        2
  •  1
  •   Cristik    5 年前

    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 .

        3
  •  0
  •   Mojtaba Hosseini    5 年前

    虽然您的解决方案不能帮助您实现更快的负载,但您必须完成繁重的工作 async

    你的问题是当你 instantiateViewController 它将创建一个新的视图控制器,该控制器与您稍后将看到的完全不同。因此,你必须 window 在appDelegate中:

    let controller = window?.rootViewController as? modeDescriptionViewController
    

    然后您可以强制它加载其视图(完全不推荐)

    Controller.loadView()
    

    然后它会自动调用viewDidLoad

    未加载,您可以调用 makeKeyAndVisible() 在上面。